从哪里开始优化/添加索引以加快查询速度?

时间:2011-09-13 17:44:01

标签: mysql search optimization indexing

我不确定从哪里开始在我的网站的搜索部分减少此查询,这样就不需要这么长时间。您在各种表上运行搜索,并主要从“项目”表中获取过滤结果,目前它(并且像它一样搜索)有时超过10秒。问题的一部分是组成sql的php代码很脏,当然,我不习惯有一般我需要优化的大量查询,但是我可以使用哪些技术来确定添加位置像这样的查询中的索引?

查询

SELECT
    items.ItemId,
    items.Name,
    items.BrandCode,
    items.BrandCategoryId,
    items.CatalogPage,
    items.PriceRetail,
    items.PriceSell,
    items.PriceHold,
    items.Descr,
    items.GenderId,
    products.ImagetnURL,
    products.FlagDefault,
    products.ProductId,
    products.Code AS ProductCode,
    products.Name AS ProductName,
    brands.Name AS BrandName,
    items.FlagStatus AS ItemFlagStatus
FROM
    items,
    products,
    brands,
    productsizes,
    searchsizechartsizes,
    sizechartsizes
WHERE
    items.ItemId = products.ItemId AND
    items.BrandCode = brands.Code AND
    items.FlagStatus != 'U' AND
    products.FlagStatus != 'U' AND
    items.TypeId = '10' AND
    searchsizechartsizes.SearchSizeChartId = '11' AND
    searchsizechartsizes.Size = sizechartsizes.Size AND
    sizechartsizes.SizeChartId = productsizes.SizeChartId AND
    productsizes.ProductId = products.ProductId
GROUP BY
    items.ItemId
ORDER BY
    items.Name
LIMIT
    0, 15;

日志显示14秒执行时间,检查300万行

# Query_time: 14  Lock_time: 0  Rows_sent: 15  Rows_examined: 2901565

查询结果摘要

+--------+----------------------+-----------+-----------------+-------------+-------------+-----------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+----------------------------+-------------+-----------+-------------+------------------------------------------+-------------------+----------------+
| ItemId | Name                 | BrandCode | BrandCategoryId | CatalogPage | PriceRetail | PriceSell | PriceHold | Descr | GenderId | ImagetnURL  | FlagDefault | ProductId | ProductCode | ProductName | BrandName         | ItemFlagStatus |
+--------+----------------------+-----------+-----------------+-------------+-------------+-
|   3376 | 10-inch Pull On Boot | RW        |            2801 |          24 |      189.99 |    189.99 |    189.99 | Full grain brown leather - blah blah blah |        1 | images/rw/rw-2249tn.jpg    | Y           |      4345 | 2249        | Brown Full Grain Turbo Vegas Leather                    | Red Wing Work     | A              | 
|   9340 | 11                   | RR        |            NULL |           1 |      300.00 |    300.00 |    300.00 | The Engineer 11" boot from Red Wing Shoes�  blah blah blah... |        1 | images/rr/rr-2990tn.jpg    | Y           |     16749 | 2990        | Black Harness Calfskin                                  | Red Wing Heritage | A              
~~~~~~ other results here redacted for space reasons ~~~~~~
15 rows in set (13.33 sec)

解释查询

mysql> explain SELECT items.ItemId, items.Name, items.BrandCode, items.BrandCategoryId, items.CatalogPage, items.PriceRetail, items.PriceSell, items.PriceHold, items.Descr, items.GenderId, products.ImagetnURL, products.FlagDefault,  products.ProductId, products.Code as ProductCode, products.Name as ProductName, brands.Name as BrandName, items.FlagStatus as ItemFlagStatus  FROM items, products, brands, productsizes, searchsizechartsizes, sizechartsizes  WHERE items.ItemId = products.ItemId AND items.BrandCode = brands.Code AND items.FlagStatus != 'U' AND products.FlagStatus != 'U' AND items.TypeId = '10' AND (searchsizechartsizes.SearchSizeChartId = '11' AND searchsizechartsizes.Size = sizechartsizes.Size AND sizechartsizes.SizeChartId = productsizes.SizeChartId AND productsizes.ProductId = products.ProductId)   group by items.ItemId  ORDER BY items.Name LIMIT 0, 15;
+----+-------------+----------------------+--------+------------------------------------------------+-------------+---------+----------------------------------------+------+---------------------------------+
| id | select_type | table                | type   | possible_keys                                  | key         | key_len | ref                                    | rows | Extra                           |
+----+-------------+----------------------+--------+------------------------------------------------+-------------+---------+----------------------------------------+------+---------------------------------+
|  1 | SIMPLE      | searchsizechartsizes | ref    | PRIMARY,Size                                   | PRIMARY     | 4       | const                                  |    2 | Using temporary; Using filesort | 
|  1 | SIMPLE      | brands               | ALL    | NULL                                           | NULL        | NULL    | NULL                                   |   40 |                                 | 
|  1 | SIMPLE      | sizechartsizes       | ref    | Size,SizeChartId                               | Size        | 33      | shermanbros.searchsizechartsizes.Size  |  217 | Using where                     | 
|  1 | SIMPLE      | productsizes         | ref    | ProductId,SizeChartId                          | SizeChartId | 5       | shermanbros.sizechartsizes.SizeChartId |   17 | Using where                     | 
|  1 | SIMPLE      | products             | eq_ref | PRIMARY,FlagStatus,flagstatusanddefault,ItemId | PRIMARY     | 4       | shermanbros.productsizes.ProductId     |    1 | Using where                     | 
|  1 | SIMPLE      | items                | eq_ref | PRIMARY,BrandCode,TypeId,FlagStatus,ItemsIndex | PRIMARY     | 4       | shermanbros.products.ItemId            |    1 | Using where                     | 
+----+-------------+----------------------+--------+------------------------------------------------+-------------+---------+----------------------------------------+------+---------------------------------+
6 rows in set (0.02 sec)

项目表的结构

mysql> show create table items;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| items | CREATE TABLE `items` (
  `ItemId` int(11) NOT NULL auto_increment,
  `Code` varchar(25) default NULL,
  `Name` varchar(100) default NULL,
  `BrandCode` char(2) default NULL,
  `CatalogPage` int(3) default NULL,
  `BrandCategoryId` int(11) default NULL,
  `TypeId` int(11) default NULL,
  `StyleId` int(11) default NULL,
  `GenderId` int(11) default NULL,
  `PriceRetail` decimal(6,2) default NULL,
  `PriceSell` decimal(6,2) default NULL,
  `PriceHold` decimal(6,2) default NULL,
  `Cost` decimal(6,2) default NULL,
  `PriceNote` longtext,
  `FlagTaxable` char(1) default NULL,
  `FlagStatus` char(1) default NULL,
  `FlagFeatured` char(1) default NULL,
  `MaintFlagStatus` char(1) default NULL,
  `Descr` longtext,
  `DescrNote` longtext,
  `ImagetnURL` varchar(50) default NULL,
  `ImagefsURL` varchar(50) default NULL,
  `ImagelsURL` varchar(50) default NULL,
  `DateCreated` date NOT NULL default '0000-00-00',
  `DateStatus` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `AdminNote` text,
  PRIMARY KEY  (`ItemId`),
  KEY `BrandCode` (`BrandCode`),
  KEY `Name` (`Name`),
  KEY `TypeId` (`TypeId`),
  KEY `StyleId` (`StyleId`),
  KEY `GenderId` (`GenderId`),
  KEY `FlagStatus` (`FlagStatus`),
  KEY `ItemsIndex` (`TypeId`,`FlagStatus`,`ItemId`)
) ENGINE=MyISAM AUTO_INCREMENT=10216 DEFAULT CHARSET=latin1 | 
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

项目表

上的现有索引
mysql> show indexes from items;
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name   | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| items |          0 | PRIMARY    |            1 | ItemId      | A         |        8678 |     NULL | NULL   |      | BTREE      |         | 
| items |          1 | BrandCode  |            1 | BrandCode   | A         |          36 |     NULL | NULL   | YES  | BTREE      |         | 
| items |          1 | Name       |            1 | Name        | A         |        8678 |     NULL | NULL   | YES  | BTREE      |         | 
| items |          1 | TypeId     |            1 | TypeId      | A         |          17 |     NULL | NULL   | YES  | BTREE      |         | 
|     items |          1 | StyleId    |            1 | StyleId     | A         |          41 |     NULL | NULL   | YES  | BTREE      |         | 
| items |          1 | GenderId   |            1 | GenderId    | A         |           3 |     NULL | NULL   | YES  | BTREE      |         | 
| items |          1 | FlagStatus |            1 | FlagStatus  | A         |           6 |     NULL | NULL   | YES  | BTREE      |         | 
| items |          1 | ItemsIndex |            1 | TypeId      | A         |          17 |     NULL | NULL   | YES  | BTREE      |         | 
| items |          1 | ItemsIndex |            2 | FlagStatus  | A         |          52 |     NULL | NULL   | YES  | BTREE      |         | 
| items |          1 | ItemsIndex |            3 | ItemId      | A         |        8678 |     NULL | NULL   |      | BTREE      |         | 
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
10 rows in set (0.00 sec)

它似乎已经在各个列上有一个索引,但是这些索引在这个搜索查询方面仍然很慢。还有一个关于typeid,flagstats,itemid的多索引,可以优化单独的查询。

是的,正如你所看到的,物品表本身就是一只野兽,这可能无济于事。

1 个答案:

答案 0 :(得分:4)

查看FROM和WHERE子句:

FROM
    items,
    products,
    brands,
    productsizes,
    searchsizechartsizes,
    sizechartsizes
WHERE
    items.ItemId = products.ItemId AND
    items.BrandCode = brands.Code AND
    items.FlagStatus != 'U' AND
    products.FlagStatus != 'U' AND
    items.TypeId = '10' AND
    searchsizechartsizes.SearchSizeChartId = '11' AND
    searchsizechartsizes.Size = sizechartsizes.Size AND
    sizechartsizes.SizeChartId = productsizes.SizeChartId AND
    productsizes.ProductId = products.ProductId

您已将所有连接逻辑放入WHERE子句中,这在阅读查询时无益。使用显式连接语法,我们可以重写如下:

FROM
    items
    JOIN products ON items.ItemId = products.ItemId
    JOIN brands ON items.BrandCode = brands.Code
    JOIN productsizes ON products.ProductId = productsizes.ProductId
    JOIN sizechartsizes ON sizechartsizes.SizeChartId = productsizes.SizeChartId
    JOIN searchsizechartsizes ON sizechartsizes.Size = searchsizechartsizes.Size
WHERE
    items.FlagStatus != 'U' AND
    items.TypeId = '10' AND
    products.FlagStatus != 'U' AND
    searchsizechartsizes.SearchSizeChartId = '11'

这使得更清楚的是发生了什么。

看起来你在ItemsIndex中有一个很好的候选索引。 (顺便说一下 - TypeID上的索引是多余的,应该删除,因为TypeID是ItemsIndex的左前缀。)不幸的是,MySQL的查询优化器似乎认为从后到前进行连接更有意义,从table searchsizechartsizes。我不确定为什么会这样做,但我注意到表品牌显然没有定义可用的键。研究这个可能是个好主意。