Mysql

通過簡單的子查詢在大表中使用 OFFSET

  • December 21, 2013

在大表中使用的性能緩慢OFFSET已在各種部落格中廣泛討論,最有效的方法是使用INNER JOINas

SELECT *
FROM table
INNER JOIN (
SELECT id
FROM table
LIMIT 10 OFFSET 100000)
AS results USING(id);

但我想知道INNER JOIN一個簡單的子查詢有什麼好處

SELECT *
FROM table
WHERE id >
(SELECT id
FROM table
LIMIT 1 OFFSET 100000)
LIMIT 10;

或更方便

SELECT *
FROM table
WHERE id IN
(SELECT id
FROM table
LIMIT 10 OFFSET 100000);

在下面的範例中,假定主鍵,但顯然可以添加ORDER BY其他命令甚至子句。WHERE我的問題是關於性能INNER JOIN或簡單子查詢的比較。

在您的特定情況下,我會LEFT JOIN改用。為什麼?

LEFT JOIN查詢中,您可以指定所需的鍵以及要獲取和連接的順序,同時INNER JOIN讓 MySQL 查詢優化器決定哪個是最好的。在某些情況下,EXPLAIN 計劃可能看起來很糟糕,但仍能提供良好的性能。

代替

SELECT *
FROM table
INNER JOIN (
SELECT id
FROM table
LIMIT 10 OFFSET 100000)
AS results USING(id);

翻轉查詢以首先獲得鍵

SELECT B.*
FROM (SELECT id FROM table LIMIT 10 OFFSET 100000) A
LEFT JOIN table B USING (id);

從那裡,您可以在子查詢 A 中通過內部控制順序

SELECT B.*
FROM (SELECT id FROM table LIMIT 10 OFFSET 100000 ORDER BY ...) A
LEFT JOIN table B USING (id);

或之後USING (id)

SELECT B.*
FROM (SELECT id FROM table LIMIT 10 OFFSET 100000) A
LEFT JOIN table B USING (id)  ORDER BY ...;

這樣,您應該能夠在定位實際數據之前通過鍵導航(或分頁)。要使用經驗證據證明這一點,請參閱我的 StackOverflow 文章(從聯接表中獲取單行)關於使用LEFT JOIN主鍵。

試一試 !!!

引用自:https://dba.stackexchange.com/questions/55435