簡體   English   中英

MySQL慢查詢-使用Filesort

[英]MySQL Slow Query - Using Filesort

我正在嘗試在我的MySQL數據庫上運行一個查詢,該查詢需要70秒鍾以上的時間才能運行,而我對於為什么不使用索引的問題scratch之以鼻。

這是查詢:

SELECT PriceId, InstrumentId, Date, Open, High, Low, Close, Volume, UnadjustedClose
FROM price
ORDER BY InstrumentId, Date DESC

價格表具有一個帶有InstrumentId,Date的索引(以及其他索引)。 該表本身有8000萬行,由2個整數,一個日期,一個長整數和5個小數組成。

說明命令的類型為ALL,對於可能的鍵,鍵和引用,類型為Null,並告訴我系統正在使用文件排序。

這是我從系統中得到的最好的嗎? 我希望索引可以用來使排序更快。

添加:

這是表的定義:

PriceId int PK, NN, AI
InstrumentId int NN
Date Date NN
Open Decimal(12,4)
High Decimal(12,4)
Low Decimal(12,4)
Close Decimal(12,4)
UnadjustedClose Decimal(12,4)
Volume BigInt

Indexes:

Primary -> PriceId
IX_InstrumentId -> InstrumentId
IX_Date -> Date
IX_InstrumentDate -> InstrumentId, Date

解釋輸出為:

id: 1
select_type: Simple
table: price
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 77926335
Extra: using filesort

優化器將不使用索引,因為您正在檢索所有行,並且索引不包含您嘗試獲取的所有列。 這意味着該索引不是覆蓋索引。

在大多數情況下,使用索引和基於索引的記錄查找來檢索額外的列要比掃描整個表(當您檢索所有內容時)效率低。

您有一些選擇:

  • 在索引中包括所有必需的列:這需要更多空間並減慢寫操作的速度。
  • 根據索引的第一列向查詢添加過濾器。 如果篩選器具有足夠的選擇性(將所需的行數縮減到合理的水平),則服務器將使用您的索引。
  • 將數據過濾到合理大小
  • 在應用程序中進行排序
  • 將主鍵(群集)修改為(InstrumentID ASC, Date DESC)

編輯關於最后一個選項的更多信息

您的表看起來像一個日志表。 在日志表中,向每個記錄添加唯一的整數ID以消除重復似乎是一個好習慣(但在大多數情況下不是這樣)。 但是,在大多數情況下,您不使用該ID。 在MySQL中,主鍵也是集群鍵(這意味着數據將在磁盤上以該順序排序-或多或少,現在可以原諒碎片。)

在日志表中,最好使用記錄的實體的ID和時間戳(在您的情況下為InstrumentID,Date)作為聚簇索引(MySQL中的主鍵)。 當您這樣做時,數據的順序將適合常見的業務需求,這意味着查詢性能會更好。

如果InstrumentID和Date是唯一的(我認為應該是這樣,那么一個工具不能同時具有多個價格,並且在不到一秒鍾的時間內更改價格確實很少),那么復合索引可能會更好。 (並且比自動生成的整數值增加了更好的分區表的選項)。

旁注:如果您按日期進行過濾或排序的頻率高於按儀器ID進行的頻率,則可以更改PK中列的順序。

編輯結束

您應該回答一些問題,以找到實現目標的更好方法:

  • 為什么需要從表中檢索所有80M條記錄?
  • 您的應用程序真的使用所有這些嗎?
  • 如果是,是否可以在應用程序級別而不是數據庫級別進行排序?
  • 記錄的順序真的很重要嗎?

由於行數太多,因此無法加快速度。 從該查詢創建一個Materialized View ,一旦創建,訪問將更快。

MySQL不支持Materialized View ,因此您可以使用此處的教程自己實現它。

暫無
暫無

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

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