2012-04-23 251 views
0

我有一個緩慢的MySQL SELECT查詢,我似乎無法排除故障。緩慢的MySQL SELECT查詢

這是一個簡單的,在大約600,000條記錄的表上。

SELECT * 
FROM `civicrm_contact` contact 
WHERE contact.external_identifier =123456 

SELECT查詢需要之間的任何地方3-6秒,這使導入另一個60萬點的記錄依賴於該查詢,完全不切實際。

的表索引示於附加的圖像:Table Indexes

如果我搜索基於contact.id = 123456則查詢時間下降到約0.004s。 contact.id是表格上的主鍵。 external_identifier是唯一的索引。

+5

你絕對需要'select *'嗎? – nico 2012-04-23 16:23:36

+0

不 - 我只是通過將其限制爲SELECT id來測試它,但查詢仍在1.5到2秒之間。所以它更好,但仍然太慢。 – bpmccain 2012-04-23 16:29:27

+0

我正在7.5GB Amazon EC2大型實例上運行它。總數據庫大小約爲1GB,因此有大量內存。 – bpmccain 2012-04-23 16:33:17

回答

0

看來你使用BTREE索引。如果您未對此列執行任何範圍查詢(使用<,>,<=>=),則可能需要使用基於散列的索引。

有關詳細信息,請參見Comparison of B-Tree and Hash Indexes

並參見here確切的語法。

+0

雖然'id'列上的'PRIMARY KEY'索引也是'BTREE',所以這並不能解釋性能差異。 – eggyal 2012-04-23 16:46:16

+0

@eggyal同意。 – yair 2012-04-23 16:48:20

0

我改變了結構,使INT類型的external_identifier而不是VARCHAR。速度已經提高到0.006s

我還沒有確定這是否將有任何更廣泛的影響

1

我知道這是一個古老的線程,但由於涉及到CiviCRM我想我會推我的想法。該修復實際上並不是最佳實踐,因爲您已更改了核心打包表之一,以加快查詢的運行速度。雖然這可能對你有好處,但我絕對不會向每個人推薦這個。

雖然您的解決方案可能突出顯示了查詢的問題,但您似乎在告訴查詢,您希望得到一個數字,但事實上數據存儲爲VARCHAR。所以我認爲只要在價值中加上單引號就可以做到這一點。

SELECT * FROM 接觸civicrm_contact WHERE = contact.external_identifier「123456」

沒有這個我敢肯定(已與Oracle工作了數年),一個隱式數據類型轉換會發生因此查詢不能使用INDEX。

解釋計劃應該證明這個理論。

感謝

帕爾韋茲

0

我半信半疑的數據類型轉換爲這個問題的。我想知道這是否與索引字段的大小限制有關。作爲一個btree意味着索引鍵可能比散列鍵要大得多。這是必要的嗎?將外部ID保存在一個單獨的表中並將它們基於數字ID鏈接起來會更好嗎?

更多的問題比這裏的答案真的。