[英]MySql Left Join very slow query
我有2表約3000/4000行。 我需要使用“左連接”建立關系,以通過搜索文本或日期時間來過濾結果。 我還需要計算分頁的總行數。 當我運行查詢時,運行速度極慢,請考慮通過控制台大約40/45秒,並從網頁上等待一分鍾以上。 關系為:對於表A的1,表B中有N。 有一個解決方案可以快速查詢嗎? 示例查詢是:
SELECT X,Y,Z, (SELECT COUNT(*)
FROM tableB WHERE tableB.idTa=tableA.id) AS CountTB
FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.idA
WHERE tableA.X LIKE'%mytext%' OR tableB.Z LIKE'%mytext%'
GROUP BY tableA.id
ORDER BY tableA.Y LIMIT 0,10
謝謝你們
當然存在ON子句。 只是從我的手機打錯了。 現在是正確的,而且非常慢:)
新更新:如果將關系從“左聯接”更改為“右聯接”,它將變得非常快。
從正確的JOIN
開始,我認為應該工作很快。
就像是:
SELECT a.X,a.Y,a.Z, COUNT(b.id) CountTB
FROM tableA a
LEFT JOIN tableB b
ON b.idTa = a.id AND b.Z LIKE'%mytext%'
WHERE a.X LIKE '%mytext%'
GROUP BY tableA.id
ORDER BY tableA.Y LIMIT 0,10
您的情況不是很清楚。 如果可以提供良好的數據樣本,我們可以找到更好的查詢。
我猜你不需要bZ LIKE'%mytext%'
。 從剛剛開始:
SELECT a.X,a.Y,a.Z, COUNT(b.id) CountTB
FROM tableA a
LEFT JOIN tableB b
ON b.idTa = a.id
WHERE a.X LIKE '%mytext%'
GROUP BY tableA.id
ORDER BY tableA.Y LIMIT 0,10
對此采取狂妄的嘗試,只是為了向您指出一般方向,以下是對該查詢的可能重寫:( 我不保證它會起作用...)
SELECT X,Y,Z, COUNT(B.id) AS CountTB
FROM tableA A
LEFT JOIN tableB B
USING (id)
WHERE tableA.X LIKE'%mytext%' OR tableB.Z LIKE'%mytext%'
GROUP BY X, Y, Z
ORDER BY tableA.Y
LIMIT 0,10
注意我的許多變化:
A
和B
標識了這些表。 LEFT JOIN
正在USING (id)
,它是WHERE A.id = B.id
簡寫。 GROUP BY
子句指定將數據按這三個變量分組。 所有這些都必須出現在SELECT
子句中,並且出現的所有其他內容都必須是聚合函數,例如COUNT()
或SUM()
。 同樣, 我不保證該查詢有效。 但它應說明一般應如何構造這樣的查詢。
除非您要從“右側”表中獲取NULLs
,否則不要使用LEFT
。 在這種情況下,我認為您不這樣做。
( SELECT COUNT... )
意味着它需要針對每行進行重新評估,而不必這樣做。 擺脫它; 使用SQL_CALC_FOUND_ROWS
。
是否正在搜索AX和BZ 相同的子字符串? 它們是否始終具有相同的價值? 如果是這樣,則僅搜索其中之一。 (例如LIKE '%...'
是查詢中昂貴的一部分。)
使用JOIN
會增加行數; 然后您添加了GROUP BY
來縮小它。 這種充氣/放氣是昂貴的。
COUNT(*)
無法通過'%mytext%'進行過濾,因此它無法滿足您“ 145行30-39行”的要求。
是AZ還是BZ?
SELECT SQL_CALC_FOUND_ROWS
a.X, a.Y,
( SELECT Z FROM tableB WHERE idTa = a.id AND Z LIKE'%mytext%' ) AS Z
FROM tableA AS a
WHERE a.X LIKE '%mytext%'
ORDER BY a.Y
LIMIT 0,10
SELECT FOUND_ROWS(); -- to get the "of 156 rows"
而你需要這些
tableB: INDEX(idTa)
tableA: INDEX(Y)
注意:由於尚不清楚A和B之間的關系是什么(1:很多vs很多:很多),因此該解決方案可能是錯誤的。 不正確性將由子查詢返回多行而跳出。
因此,我可能沒有給您“正確”的答案,但是希望我給您足夠的線索,以便您可以更緊密地聯系。
之后,也許可以通過“記住您離開的地方”而不是使用OFFSET
來使分頁更快。 看我的博客 。
如果您想進一步討論,請提供SHOW CREATE TABLE
,不要混淆列名-通常,這些名稱會提供您意圖的線索。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.