2012-03-29 82 views
1

我有以下查詢需要一分多鐘才能執行,我該如何優化它。它的速度很慢,因爲命令由o.id desc,如果我刪除它查詢執行它幾個毫秒。如何優化此查詢,執行時間超過一分鐘


select o.*, per.email, p.name 
from order o 
inner join product p 
on o.product_id=p.id 
inner join person per 
on o.person_id=per.id 
order by o.id desc 
limit 100; 

以下是解釋


1 SIMPLE p index PRIMARY FK2EFC6C1E5DE2FC 8 NULL 6886 Using index; Using temporary; Using filesort 
1 SIMPLE o ref FK67E9050121C383DB,FK67E90501FC44A17C FK67E90501FC44A17C 8 dev.p.id 58 
1 SIMPLE per eq_ref PRIMARY PRIMARY 8 dev.o.person_id 1 Using index 

所有的表都InnoDB的結果,並加入是對主鍵和外鍵。除此之外指標上電子郵件狀態訂單

的每個表中的記錄數

人:1300000 產品7,000 訂購70000

+1

請發表您的表結構以及 – 2012-03-29 11:44:10

+1

你們每個添加索引屬性您正在使用的關係? (person_id,id,product_id,..)? – blejzz 2012-03-29 11:45:35

+0

請發佈這些表上存在的所有索引 – MatBailie 2012-03-29 11:56:46

回答

1

規劃師很可能在加入之前不使用limit提示來消除訂單表中的行。所以服務器必須對所有行進行連接,然後返回一些。

試試這個:

select o.* from 
(select * order order by id desc limit 100) o 
inner join product p 
on o.product_id=p.id 
inner join person per 
on o.person_id=per.id 
order by o.id desc limit 100; 

編輯:這將只工作,如果有低保相應的行存在於產品和Person表的約束。

+0

即使這可能會加快此過程,但它不會給出準確的結果。如果這100行中的一行無法加入,該怎麼辦?那麼你會得到99行而不是100. – 2012-03-29 12:06:09

+0

你說得對。沒想過。但這也取決於表格的設置方式。如果在這些列上存在外鍵約束,那麼它不會成爲問題。 – Dojo 2012-03-29 12:07:59

+0

如果您認爲所有這些表都連接正確,則根本不需要該連接,因爲只有o。*被提取。 – 2012-03-29 12:12:57

0

是的,我明白你的問題,在這種情況下,首先將你的查詢保存在.sql文件中。 您可以在Sql Server Management工作室的工具菜單中使用名爲「數據庫引擎優化顧問」的SQL Server實用程序。

首先打開sql server並轉到工具並選擇選項「數據庫引擎優化顧問」。 然後選擇您之前存儲的文件。 現在勾選您正在使用的數據庫和查詢中使用的表格,然後點擊主菜單中的開始分析 。 它向您展示了可能的索引和實體,現在創建 以將此推薦應用於您的查詢,進入操作手冊並選擇「應用推薦」,這將在您的表上創建索引和實體並減少查詢的執行時間。

+0

OP正在使用MySQL – Simon 2012-03-29 12:10:30