2009-09-25 57 views
2

任何人都可以幫助我提高以下sql的性能。使用數據庫是Informix的在informix中提高sql的性能

SELECT 
    informix.set_reason_codes.description as reason_code, 
    count(*) as number_of_calls 
FROM 
informix.contact_history, 
informix.set_reason_codes, 
informix.customers 
WHERE 
    (informix.contact_history.reason_code = informix.set_reason_codes.reason_code) 
and ((informix.set_reason_codes.code_type = 'CONTACT_HISTORY')) 
and (informix.contact_history.customerkey = informix.customers.customerkey) 
and (informix.contact_history.call_type = 0) 
group 
    by informix.set_reason_codes.description 
order by 
    informix.set_reason_codes.description 
+0

什麼指標都存在這些表? – 2009-09-25 07:42:45

+0

對於contact_history一個指數customerkey,DATE_AND_TIME和REASON_CODE 對於集REASON_CODES一個指數code_type,REASON_CODE 對於客戶一個指數customerkey – Shalma 2009-09-25 07:54:33

回答

3

您需要通過運行該SQL使用EXPLAIN ON獲得查詢計劃,即:

SET EXPLAIN ON; 
SELECT .... 

這將優化器的計劃寫入一個文件(實際位置取決於OS和連接方法)。

一旦你有了這個,你將處於一個更好的位置,以確定你的性能問題的原因。但通常情況下,把它歸結爲這些東西:

  • 不合適的指標
  • 過時的或關於自動索引或順序掃描,你的sqexplain文件丟失索引統計信息

消息預計NESTED LOOP(索引連接)是一個非常好的指標,需要進行一些調整。如果不出意外,運行查詢,並得到解釋輸出,然後執行,

UPDATE STATISTICS MEDIUM FOR TABLE informix.contact_history; 
UPDATE STATISTICS MEDIUM FOR TABLE informix.set_reason_codes; 
UPDATE STATISTICS MEDIUM FOR TABLE informix.customers; 

如果你得到一個完全不同的結果,在性能和查詢計劃的報道,你知道你的問題是相關的統計數據。

瞭解您正在運行的Informix版本也很有用。

2

瞭解如何使用表的別名,使SQL可讀:

SELECT r.description AS reason_code, COUNT(*) AS number_of_calls 
    FROM informix.contact_history AS h, 
     informix.set_reason_codes AS r, 
     informix.customers  AS c 
WHERE h.reason_code = r.reason_code 
    AND r.code_type = 'CONTACT_HISTORY' 
    AND h.customerkey = c.customerkey 
    AND h.call_type = 0 
GROUP BY r.description 
ORDER BY r.description 

避免多餘的支架也有幫助。你可以對佈局進行辯論 - 但沿着這些線路看起來很合理。另一天,我們可以辯論使用用戶'informix'作爲表的所有者的優點或缺點 - 我建議不要這樣做,但也有人堅持認爲這是他們的最佳選擇。 (我不同意他們的推理,但顧客永遠是對的。)

至於性能,你的評論說,指標是:

  • 對於contact_history一個指數customerkey,DATE_AND_TIME和REASON_CODE 。
  • 對於set_reason_codes一個指數code_type,REASON_CODE
  • 對於客戶一個指數customerkey

你的問題的一部分就在這裏。你可能會從索引中受益:

CREATE INDEX fk_contact_history ON contact_history(reason_code); 

這將與加入的「h.reason_code = r.reason_code」幫助;現有的索引無論如何都沒有用處。

你可能會從索引中受益:

CREATE INDEX ix_set_reason_codes ON set_reason_codes(reason_code); 

然後我們到了問題的肉;你加入客戶表,但似乎沒有任何實際的理由 - 假設customerkey實際上是customers表的主鍵。

所以,你會從這個查詢得到同樣的結果:

SELECT r.description AS reason_code, COUNT(*) AS number_of_calls 
    FROM informix.contact_history AS h, 
     informix.set_reason_codes AS r 
WHERE h.reason_code = r.reason_code 
    AND r.code_type = 'CONTACT_HISTORY' 
    AND h.call_type = 0 
GROUP BY r.description 
ORDER BY r.description 
+0

我使用別名絕對同意(我被帶到一個傢伙在Informix的工作,相信即使查詢中只有一個表,也會提高性能)。 但是,如果contact_history.customerkey不能爲空,則省略與customerkey的連接只會始終返回相同的行。如果它是可空的,那麼原始查詢將只返回鏈接到客戶行中的contact_history行;建議的替換將返回contact_history中的所有行。 Shalma認爲這是正確的。 – sanmiguel 2010-03-24 18:13:23