簡體   English   中英

在where子句和order by子句之間的MySQL索引

[英]MySQL index in between where clause and order by clause

我的表結構如下所示:

CREATE TABLE test (
    id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,

    field_1 VARCHAR(60) NOT NULL,
    field_2 INT(10) UNSIGNED NULL,
    field_3 INT(10) UNSIGNED NULL,
    field_4 INT(10) UNSIGNED NULL,
    field_5 CHAR(2) NULL,
    field_6 INT(10) UNSIGNED NOT NULL,

    rank TINYINT(2) NOT NULL DEFAULT '0',   
    status TINYINT(3) NOT NULL DEFAULT '0',

    PRIMARY KEY (id),
    INDEX (status)

) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = MyISAM;

在上表中, rankstatus字段的整數值分別為0-9和0-4。

目前,該表中充滿了大約950K數據,我正在嘗試盡可能優化我的查詢。

基本上,我需要選擇帶有where子句的字段,其中where子句的字段rank為降序。

例如,以下是一些sql查詢:

SELECT field_1, field_2, field_3 FROM test WHERE field_1 = 'data1' && status IN ('0', '1', '2') ORDER BY rank DESC LIMIT 0, 20;
SELECT field_1, field_2, field_3 FROM test WHERE field_2 = '5' && status IN ('1', '2') ORDER BY rank DESC LIMIT 0, 20;
SELECT field_1, field_2, field_3 FROM test WHERE field_5 = 'US' && status IN ('0', '2') ORDER BY rank DESC LIMIT 0, 20;

在上面的查詢中, ORDER BY rank DESC非常重要。 所以我很困惑我應該在單列還是多列上添加索引。

誰能建議我最好的解決方案。

您的關鍵問題是,超過950k的行中, status列最多包含4個不同的值。 在BTREE指數上,這將是一個真正的難題。

下面提到的用於3個查詢的一些更有效的索引可能是:

INDEX forQuery1 ( field_1 , status , rank ) USING BTREE,
INDEX forQuery2 ( field_2 , status , rank ) USING BTREE,
INDEX forQuery3 ( field_5 , status , rank ) USING BTREE,

您會發現第二個查詢特別有用,但是您仍然會遇到這樣的問題,即數據集的大小的數據差異非常小,盡管您的EXPLAIN會可能會顯示LIMIT來減輕這種影響。 提到的索引應該適合於確定要返回哪些行。

有關MySQL如何使用索引的更多信息,請瀏覽13.1.13。 CREATE INDEX語法 ,尤其是有關B樹索引特征的部分以及以下摘錄

如果表具有多列索引,則優化器可以使用索引的任何最左前綴來查找行。 例如,如果在(col1,col2,col3)上有一個三列索引,則在(col1),(col1,col2)和(col1,col2,col3)上都有索引搜索功能。

如果列不構成索引的最左前綴,則MySQL無法使用索引。 假設您在這里顯示了SELECT語句:

有時,即使索引可用,MySQL也不使用索引。 發生這種情況的一種情況是,優化器估計使用索引將需要MySQL訪問表中很大比例的行。 (在這種情況下,表掃描可能會更快,因為它需要更少的查找。)但是,如果這樣的查詢使用LIMIT只檢索某些行,則MySQL仍然使用索引,因為它可以更快地找到返回結果的幾行。

另外需要注意的是,您不需要引用數字數據類型,因此field_2 = 5 && status IN ( 1 , 2 )是有效的(實際上,由於引用整數數據類型而不是引用數據,我過去曾遇到過一些奇怪的問題將其指定為數字)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM