mysql5.6 分頁查詢優化


mysql5.6 分頁查詢優化html

場景:mysql

表結構:主鍵(非自增)contentCode(varchar),過濾條件列爲updateTime(timeStamp),已經爲timestamp創建索引。sql

搜索sql爲:函數

SELECT
	*
FROM
	my_hello_table
WHERE
	updateTime >= '2019-04-21 14:37:38'
AND updateTime <= '2019-04-27 16:36:57'
LIMIT 599000,
 1000

 

問題:數據在分頁到60w後,分頁查詢時間爲5.8s左右。沒法忍受。測試

緣由:雖然走了索引,但mysq5.6 對於分頁的操做是先根據過濾條件去索引查詢出全部的updateTime,而後根據updateTime依次查詢出60w數據,而後拋棄前59w9k條查詢出數據,而後獲取最後的1k條。優化

分頁的這種越到後面用時越長的問題,是mysql5的一個失誤,在mysql8以後的版本貌似獲得瞭解決。code

優化:整體思路是走索引,走索引,仍是走索引。htm

首先咱們經過分頁條件查詢,只走updateTime索引,而後獲取全部的主鍵,此時mysql是不回主表的。而後經過in 查詢主表中全部在此範圍的數據。blog

參考http://www.javashuo.com/article/p-qefdncmw-dz.html排序

有以下sql:

SELECT
	*
FROM
	my_hello_table
WHERE
	contentCode IN (
		SELECT
			contentCode
		FROM
			my_hello_table
		WHERE
			updateTime > '2019-04-21 14:37:38'
		AND updateTime <= '2019-04-27 16:36:57'
		LIMIT 599000,
		1000
	)
);

可是,惋惜的是,會有以下問題:

This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

解決方法有 僞表進行錶鏈接操做 和 in裏面使用limit 參考:

https://www.cnblogs.com/c-h-y/p/9946813.html

最後 的sql爲:

in 裏面 用limit 的sql:

SELECT
    *
FROM
    my_hello_table
WHERE
    contentCode IN (
        SELECT
            t.contentCode
        FROM
            (
                SELECT
                    contentCode
                FROM
                    my_hello_table
                WHERE
                    updateTime > '2019-04-21 14:37:38'
                AND updateTime <= '2019-04-27 16:36:57'
                LIMIT 599000,
                1000
            ) AS t
    );


 僞表 錶鏈接

SELECT
    a.*
FROM
    my_hello_table a
INNER JOIN (
    SELECT
        contentCode
    FROM
        my_hello_table
    WHERE
        updateTime > '2019-04-21 14:37:38'
    AND updateTime <= '2019-04-27 16:36:57'
    LIMIT 599000,
    1000
) AS b ON a.contentCode = b.contentCode

兩種方式推薦第二種。避免了in語句。進行explain診斷會發現第二種效率高不少。

最後通過測試,查詢時間由原來的5.8秒 優化到1.2s左右,優化率搞到400%。

記錄下sql語句的完整執行順序

一、from子句組裝來自不一樣數據源的數據;

二、where子句基於指定的條件對記錄行進行篩選; 

三、group by子句將數據劃分爲多個分組; 

四、使用匯集函數進行計算;

五、使用having子句篩選分組; 

六、計算全部的表達式; 

七、使用order by對結果集進行排序。

相關文章
相關標籤/搜索