2017-03-06 206 views
0

Iam使用MySQL運行我的Rails應用程序。我開始審查我的MySQL慢速查詢日誌,我看到大約有6000行主要重複以下查詢。MySQL - 提高查詢性能

SET timestamp=1488423689; 
SELECT COUNT(*) FROM `system_events` 
    WHERE (notified 
     AND id != 476200 
     AND customer_id = 1 
     AND classification = 50039 
     AND created_at >= '2017-02-27 03:01:26'); 
# Time: 170302 3:01:49 
# Thread_id: 2972915 Schema: ash#### Last_errno: 0 Killed: 0 
# Query_time: 7.195183 Lock_time: 0.000029 Rows_sent: 1 Rows_examined: 26296 Rows_affected: 0 Rows_read: 26296 
# Bytes_sent: 63 

系統事件表

enter image description here

系統活動說明:

enter image description here

是否SELECT COUNT(*)有性能問題?如何解決它們?

回答

1

問題是您只有單列索引,而where標準將由多列索引提供。 MySQL試圖通過使用索引合併來彌補,但這並不像使用單個索引那樣高效。根據您如何使用

我將創建customer_idclassificationcreated_at領域一個多列索引,我也將移動notified現場發回的地方標準(應該是最後一個條件。

notified場,這似乎是一個0或1的值布爾字段因此將其添加到索引不會真正增加索引的選擇性

0
INDEX(notified, customer_id, classification, created_at) 

created_at需求是最後的;其餘的可在任何 訂購。

  • 所有4列只有相關的行數會被觸及。
  • 退出notified需要查看更多行,並且必須跳過該列中具有錯誤值的任何行。 (因此,我不同意@Shadow是否包含notified。)
  • 現有索引做了兩列的「索引合併相交」,這可能是總是比具有組合索引慢。
  • 沒有看到SHOW CREATE TABLE,我不能說下面的 「覆蓋」 指標是否會得到更好的,還是含蓄地存在:

    INDEX(通知,CUSTOMER_ID,分類,created_at,ID)

如果您不期望20億客戶,請考慮使用小於4個字節的東西INT。一個2字節的SMALLINT UNSIGNED允許多達64K的ID。 (對於其他INTs同上。)