[英]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 *
)。 在這種情況下,您可以使用幾種方法來最大化查詢性能:
總有其他方法可以提高性能(例如,通過減小每行的大小),但是主要方法是減少必須訪問的行數,並增加順序訪問而不是隨機訪問的行的百分比。 上面的索引建議都可以做到。
以下為原始答案:
在不知道確切的模式或查詢計划的情況下,此查詢的主要性能問題是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.