2012-10-16 65 views
1

我想在這裏查詢兩個相當大的表來拉動一些結果,並且效率有些麻煩。低效JOIN方法?

注意:我只包含了相關的列,使其看起來不那麼雜亂!

表A(股票)具有的productID,OWNERID,數列

表B(業主)的ID,accountHolderID和名稱列

我想要做的就是查詢表A和地方的productID = X拉起Stock.productID,Stock.accountHolderID和Owners.name。這兩個表之間的關係是Stock.ownerID = Owners.ID,所以如果WHERE條件拉出5個productID,那麼我希望TableB中的名稱與TableA中的ownerID匹配。

在這種情況下,唯一的唯一的ID從表B

Owners.ID

只是做TableA上的基本的SELECT查詢這些產品需要15秒但是當我添加一個INNER JOIN匹配的東西最多TABLEB查詢需要更長的時間,10分鐘以上。我猜我已經設計了這個查詢效率低下。

SELECT 
Owners.name, 
Stock.productID, 
Stock.ownerID 
FROM Stock 
INNER JOIN 
Owners 
ON Stock.ownerID = Owners.ID 
WHERE 
Stock.productID = 42301679 

如何使此查詢更有效?

將OR添加到WHERE條件允許我一次拉多個productID嗎?

+0

15秒似乎很長一段時間。我可以問問環境嗎? –

+0

似乎是一個非常標準的查詢。這些表上的行數是多少?哪些索引在那裏?另外,你使用的是什麼DBMS? (mysql,oracle等)。我的第一個猜測是缺少索引。 – Jody

+0

只是再次進行基本的SELECT查詢來檢查時間,實際上是9秒。 mySQL環境。股票表中包含了不到21,489,000個條目,Owners表格大約是439,000 – Jay

回答

1

基於您的評論多productIDs,它看起來像你在owner.id字段中缺少一個非常重要的索引。現在,請記住,此索引將有助於此查詢,但您必須考慮對此表運行的所有其他查詢,以確定添加該索引是否是一個好主意。

在29M行上,頻繁插入的表上有一個索引,可能會對插入時間產生顯着影響。

這可能是不同的應用程序需要不同的索引 - 即您的OLTP應用程序和您的報告應用程序(這可能只是您運行即席查詢)的情況。一個常見的解決方案是讓第二臺服務器運行您的報告/數據倉庫查詢,該查詢的索引已正確調整爲此函數。

祝你好運。

+0

好點Jody。令人遺憾的是,由於數據庫的性質,Owners表格處於不斷變化的狀態,其中更新查詢會不斷實時運行。我猜如果我要進一步對它進行索引,性能權衡將會非常重要。雖然它主要只是更新查詢而不是INSERT,但其他行會更改,但ID不會偶爾添加新的ID,因此在這種情況下索引ID是否值得? – Jay

+0

很難說如何添加索引會影響性能。我不確定更新是否需要以插入方式更新索引。我的建議是,隔離數據庫並運行一些基準測試,不管有沒有新的索引,一般都會非常仔細地進行,並且需要大量的干係人蔘與進來。另外,請記住,索引將需要涵蓋被選擇爲最有效的兩個字段。 – Jody

1

傻冒查詢看起來正確 或許我們能看到的模式

爲了拉一次就可以使用IN操盤OR

SELECT 
Owners.name, 
Stock.productID, 
Stock.ownerID 
FROM Stock 
INNER JOIN 
Owners 
ON Stock.ownerID = Owners.ID 
WHERE 
Stock.productID IN (42301679,123232,232324) 
+0

哦,我完全忘記了IN,這很有幫助謝謝=) – Jay

1

如果productID在庫存表中是唯一的,則將其作爲索引是有意義的,這可以大大提高其他人提到的性能。

另一個性能增益來自設置特定長度的Owner.name字段。在mySQL中,VARCHAR可用於各種長度的字符串,而CHAR(32)列指示該名稱將始終佔用32個字符。額外的未使用空間只是填充的,所以你可以真正將(32)看作是指示最大長度。性能優勢來自數據庫現在確切知道每行佔用多少字節的事實,並且它可以使用此信息來提高查找時間。

+0

不幸的是,productID不是一個獨特的領域,大部分使用數千次。削減Owner.name字段很可能是一個選項。謝謝 – Jay