簡體   English   中英

如何優化此查詢?

[英]How do i optimize this query?

我有一個非常具體的查詢。 我嘗試了很多方法,但無法達到我想要的性能。

SELECT *
FROM
    items
WHERE
    user_id=1
AND
    (item_start < 20000 AND item_end > 30000)

我創建並在user_id,item_start,item_end上建立索引

這不起作用,我刪除了所有索引並創建了新索引

user_id,(item_start,item_end)

這也沒有用。

(user_id,item_start和item_end為int)

編輯:數據庫是MySQL 5.1.44,引擎是InnoDB

更新:根據下面的注釋,您需要查詢中的所有列(因此,您的SELECT * )。 在這種情況下,您可以使用幾種方法來最大化查詢性能:

  1. 創建(或更改)您的聚簇索引位於item_user_id,item_start,item_end上。 這將確保為每個查詢檢查盡可能少的行。 根據下面的原始答案,這種方法可能會加快此特定查詢的速度,但可能會減慢其他查詢的速度,因此您需要格外小心。
  2. 如果更改集群索引不切實際,則可以在item_user_id,item_start,item_end和查詢所需的任何其他列上創建非集群索引。 這將在某種程度上減慢插入速度,並使表所需的存儲空間增加一倍,但會加快此特定查詢的速度。

總有其他方法可以提高性能(例如,通過減小每行的大小),但是主要方法是減少必須訪問的行數,並增加順序訪問而不是隨機訪問的行的百分比。 上面的索引建議都可以做到。

以下為原始答案:

在不知道確切的模式或查詢計划的情況下,此查詢的主要性能問題是SELECT *強制對每一行的存儲索引進行查找。 如果特定用戶ID的匹配行數量很多,並且如果聚簇索引的第一列不是item_user_id,那么這將是非常低效的操作,因為您的磁盤將嘗試從聚簇inedx中獲取大量隨機分布的行。

換句話說,即使完全過濾所需的行也很快速(因為有索引),但實際上獲取數據的速度較慢。

但是,如果您的聚集索引由item_user_id,item_start,item_end排序,則可以加快處理速度。 請注意,這不是萬能葯,因為如果您有其他查詢依賴於不同的順序,或者如果您以不同的網絡順序插入行,則最終可能會減慢其他查詢的速度。

影響較小的解決方案是創建一個覆蓋索引,該索引僅包含所需的列(也按item_user_id,item_start,item_end排序,然后添加所需的其他列)。 然后將查詢更改為僅拉回所需的列,而不是使用SELECT *

如果您可以發布有關DBMS品牌和版本的更多信息以及表的架構,我們可以為您提供更多詳細信息。

您需要選擇*嗎? 如果沒有,則可以在user_id,item_start,item_end上創建索引,並在SELECT部分​​中將所需字段包括在內。 所有這些都假設您使用的是Microsoft SQL Server 2005+

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM