簡體   English   中英

優化我的mysql查詢以使用索引進行排序

[英]Optimizing my mysql query to use index for sorting

我需要您的幫助來優化下面的查詢。 讓我們假設我們有一個用於文章的Web應用程序。 該軟件使用兩個表;一個是商品表,另一個是用戶表。 article表包含創建文章的日期,id,正文,標題和部分。 讓我們假設我們有一個稱為“新聞”的板塊,並且有100萬條文章屬於新聞板塊。 因此,在這種情況下,如何優化以下查詢:

SELECT username,title FROM article,users 
WHERE article.auther_id=users.id AND section LIKE 'news' 
ORDER BY article.date DESC 
LIMIT 0,40

表結構為:

CREATE TABLE `article` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`title` VARCHAR( 100 ) NOT NULL ,
`body` VARCHAR( 200 ) NOT NULL ,
`date` VARCHAR( 30 ) NOT NULL ,
`auther_id` INT NOT NULL ,
`section` VARCHAR( 30 ) NOT NULL
) ENGINE = MYISAM ;


CREATE TABLE `users` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 30 ) NOT NULL
) ENGINE = MYISAM ;

我試圖創建一個由節和日期組成的索引,但這並不是最好的,因為如果我們有200萬條記錄,而其中一百萬條屬於一個節,則數據庫將掃描一百萬行。

在article.auther_id上添加索引。 除了您已經在日期和部分中添加的索引。

從查詢來看,您似乎需要在節上創建索引並在日期上創建索引(兩個單獨的索引)。 嘗試添加這些內容,然后查看說明計划,以查看它們是否有效,或者是否存在其他一些可能有所幫助的調整。

好的,首先將DATE數據類型用於日期,因為這將比使用VARCHAR快得多。

其次,您只需要在商品表的創建表語法中添加以下鍵即可。

KEY auther_id (auther_id),
KEY section (section),

沒什么關系,但是如果您使用的是InnoDB,則可以另外將auther_id用作外鍵。

另外,如果您不需要使用' LIKE ',請-只需檢查section="news"就會更快。 (如果有一個有限的列表,您甚至可以對部分使用ENUM 。)

就像其他人所說的那樣,日期,部分和auther_id上的索引。 根據這個:

http://www.mysqlperformanceblog.com/2008/08/22/multiple-column-index-vs-multiple-indexes/

擁有一個多列索引而不是三個獨立的索引可能會非常有益,例如:

...
key idx_combo (auther_id, section, date)
...

在表定義中。

最好的辦法是根據日期/節創建一個分區表。

然后創建本地分區索引,以使性能更高。

您需要在(section, date)上創建索引。

不要將auther_id列為auther_id列:文章將成為連接的auther_id ,並且不會在此列上進行搜索。

由於查詢中的LIMIT 0, 40 ,因此MySQL不必掃描整個索引。 它只會選擇前40條記錄。

這是要檢查的測試腳本:

CREATE TABLE `article` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`title` VARCHAR( 100 ) NOT NULL ,
`body` VARCHAR( 200 ) NOT NULL ,
`date` VARCHAR( 30 ) NOT NULL ,
`auther_id` INT NOT NULL ,
`section` VARCHAR( 30 ) NOT NULL
) ENGINE = MYISAM ;


CREATE TABLE `users` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 30 ) NOT NULL
) ENGINE = MYISAM ;

INSERT
INTO    article
SELECT  id,
        CONCAT('Title ', id),
        CONCAT('Body ', id),
        DATE_FORMAT('2009-12-18' - INTERVAL id MINUTE, '%Y-%m-%d %H:%i:%S'),
        (id - 1) % 500 + 1,
        'news'
FROM    t_source;

INSERT
INTO    users
SELECT  id, CONCAT('Username ', id)
FROM    t_source
LIMIT 500;

CREATE INDEX ix_article_section_date ON article (section, date);

SELECT  username,title
FROM    article
JOIN    users
ON      users.id = article.auther_id
WHERE   section = 'news'
ORDER BY
        article.date DESC
LIMIT 0, 40;

t_source是一個虛擬表,其中有1,000,000行。

最終查詢在計算機上的0.0018 s立即完成

這是執行計划:

1, 'SIMPLE', 'article', 'range', 'ix_article_section_date', 'ix_article_section_date', '92', '', 999998, 'Using where'
1, 'SIMPLE', 'users', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'test.article.auther_id', 1, ''

暫無
暫無

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

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