2012-05-05 36 views
2

表:如何優化MySQL的ORDER BY +巨大LIMIT偏移

CREATE TABLE `test` (
    `uid` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `rating` smallint(5) unsigned NOT NULL DEFAULT '100', 
    PRIMARY KEY (`uid`), 
    KEY `rating` (`rating`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

此查詢運行速度不夠快(0.015s):

SELECT uid FROM test ORDER BY rating DESC LIMIT 0,100 

但隨着大LIMIT抵消它的運行速度非常慢(2.215 s):

SELECT uid FROM test ORDER BY rating DESC LIMIT 10000,100 

我該如何擺脫巨大的極限補償?

+1

你可以編輯你的問題,並在展位案例中添加查詢時間?因此,我們可以理解「慢」和「足夠快」的含義 – kappa

+0

@kappa添加時間度量 –

回答

1

提高性能的最簡單方法是對主鍵進行排序。

由於您無法通過rating列真正做到這一點,所以您可以改爲作弊。

創建該表:

CREATE TABLE `test_ranks` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `uid` int(11) unsigned NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

然後投入運行的時間每X量(1分鐘,5分鐘......更新速度和時間之間它基本上是一個很好的妥協cron腳本如下需要運行):

CREATE TEMPORARY TABLE `_tmp_test_ranks` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `uid` int(11) unsigned NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

INSERT INTO `_tmp_test_ranks` (`uid`) VALUES (SELECT `uid` FROM `test` ORDER BY `rating` DESC); 

TRUNCATE `test_ranks`; 

INSERT INTO `test_ranks` SELECT * from `_tmp_test_ranks`; 

DROP TABLE `_tmp_test_ranks`; 

現在,而不是你的運行慢的選擇,你可以運行速度更快:

SELECT `uid` FROM `test_ranks` WHERE `id` BETWEEN 10000 AND 10100 ORDER BY `id` ASC 
+0

誰低估了,爲什麼? –

+1

在這種情況下是不是評級已經是覆蓋指數?我沒有投票。 – Ami

+0

@Kolink,您的解決方案非常棒!請更正以下查詢:'INSERT INTO _tmp_test_ranks(uid)VALUES(SELECT uid FROM test ORDER BY rating DESC);'INSERT INTO _tmp_test_ranks(uid)(SELECT uid FROM test ORDER BY rating DESC);' –

0

據我所知,在做了一點挖掘之後,真的沒有辦法讓你在數據庫的配置或類似的設置中設置最大限制。這取決於實現數據庫的應用程序的開發人員,以確保在應用程序邏輯內建立最大值。

+0

我不會禁止某人執行此類查詢。只是想知道如何優化極大的LIMIT偏移量並將其消除。 –

6

With LIMIT 10000, 100 MySQL必須掃描10100條記錄。如果你能記得在窗口中你的位置,它可能會更好:

SELECT uid 
FROM test 
WHERE rating > :last_rating 
ORDER BY rating DESC LIMIT 0,100 

在這種情況下:last_rating是從以前的查詢的最後得分。

+0

@Didar_Uranov,你是對的。對不起,我的意思是評分。 :)現在修復它。 – Ami

+0

該技術適用於「Previous」<->「Next」分頁。我爲你高興。我刪除了我的上述評論。 –

+1

要小心,因爲您可能會以這種方式放棄某些結果:評分空間小於空格 – kappa