【发布时间】:2011-11-16 09:28:47
【问题描述】:
我不确定从哪里开始在我网站的搜索部分减少此查询,以免花费很长时间。您在各种表格上运行搜索,并主要从“项目”表格中获取过滤结果,目前它(和类似的搜索)有时需要超过 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)
items 表上的现有索引
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 的多索引,用于优化单独的查询。
是的,如您所见,items 表本身就是一头野兽,这可能无济于事。
【问题讨论】:
-
第一条评论:查询中的 GROUP BY 子句没有意义,你没有使用任何聚合函数。它应该被删除。
标签: mysql search optimization indexing