如何在Extra中优化MYSQL: - 使用where;使用临时;使用filesort
什么是适合这个查询的索引。如何在Extra中优化MYSQL: - 使用where;使用临时;使用filesort
我试图给定索引的不同组合对于该查询,但它仍然使用tempory使用,使用文件排序等
总表中的数据 - 7,60,346
product
=“连衣裙” - 总行数= 122 554
CREATE TABLE IF NOT EXISTS `product_data` (
`table_id` int(11) NOT NULL AUTO_INCREMENT,
`id` int(11) NOT NULL,
`price` int(11) NOT NULL,
`store` varchar(255) NOT NULL,
`brand` varchar(255) DEFAULT NULL,
`product` varchar(255) NOT NULL,
`model` varchar(255) NOT NULL,
`size` varchar(50) NOT NULL,
`discount` varchar(255) NOT NULL,
`gender_id` int(11) NOT NULL,
`availability` int(11) NOT NULL,
PRIMARY KEY (`table_id`),
UNIQUE KEY `table_id` (`table_id`),
KEY `id` (`id`),
KEY `discount` (`discount`),
KEY `step_one` (`product`,`availability`),
KEY `step_two` (`product`,`availability`,`brand`,`store`),
KEY `step_three` (`product`,`availability`,`brand`,`store`,`id`),
KEY `step_four` (`brand`,`store`),
KEY `step_five` (`brand`,`store`,`id`)
) ENGINE=InnoDB ;
查询:
SELECT id ,store,brand FROM `product_data` WHERE product='dresses' and
availability='1' group by brand,store order by store limit 10;
excu..time: - (10总计,查询花费1.0941秒)
说明计划:
possible_keys: - step_one,step_two,step_three,step_four,step_five
key: - step_two
ref: - 常量,常量
行: -
额外: - 使用其中;使用临时;使用文件排序
我想这些指标
Key
step_one(product
,availability
)
Key
step_two(product
,availability
,brand
,store
)
Key
step_three(product
, availability
,brand
,store
,id
)
Key
step_four(brand
,store
)
Key
step_five(brand
,store
,id
)
真正的问题不是指数,而是防止服用LIMIT
优势GROUP BY
和ORDER BY
之间的不匹配。
这
INDEX(product, availability, store, brand, id)
将 “覆盖”,并以正确的顺序。但请注意,我已经换store
和brand
......
更改查询
SELECT id ,store,brand
FROM `product_data`
WHERE product='dresses'
and availability='1'
GROUP BY store, brand -- change
ORDER BY store, brand -- change
limit 10;
这改变了GROUP BY
下手store
,以反映ORDER BY
排序 - 这避免额外的排序。并且它将ORDER BY
更改为与GROUP BY
相同,以便两者可以合并。
考虑到这些变化,INDEX
现在可以一直到LIMIT
,从而允许处理仅查看10行,而不是更大的集合。
任何小于所有这些变化的效率都不会那么高。
进一步讨论:
INDEX(product, availability, -- these two can be in either order
store, brand, -- must match both `GROUP BY` and `ORDER BY`
id) -- tacked on (on the end) to make it "covering"
“覆盖”是指所有为SELECT
列在INDEX
被发现,因此没有必要将达到到数据。
但是... 整个查询不会使因为在SELECT
列入id
感。如果你想找到有哪些商店有可用的礼服,那么摆脱id
。如果您想列出所有可用的连衣裙,请将id
更改为GROUP_CONCAT(id)
。
谢谢先生,我明白你的观点。 –
对于索引,最好索引是step_two。产品字段用于何处,并且与可用性字段相比具有更多的变体。
夫妇的关于查询注释:
- 可用性=“1”应该可用性=使得不必要内部 - > VARCHAR转换将避免1。
- “不应该将GROUP BY品牌”用作GROUP BY,只应在将聚合函数用作选定列时使用。你试图通过团队获得什么?
是的先生我试过“SELECT ID,品牌”,但仍然使用tempory,使用filesort。请帮助 –
你试图通过小组达成什么? – slaakso
如果没有聚合函数,你的group by clause
没有意义。
如果您可以重新编写查询到
SELECT id ,store
FROM `product_data`
WHERE product='dresses'
and availability='1'
order by store limit 10;
然后在(
产品,
可用性,
店)
指数将删除所有filesorts。
见SQLFiddle:http://sqlfiddle.com/#!9/60f33d/2
UPDATE:
的SQLFiddle让您的意图明显 - 你用GROUP BY
模拟DISTINCT
。我不认为你可以摆脱你的查询中的filesort和临时表步骤,如果是这样的话 - 但我也不认为这些步骤应该是非常昂贵的。
父亲请在这里检查http://sqlfiddle.com/#!9/5280b1/1 –
这与原始请求不匹配,因为它无法执行“GROUP BY”。 –
“GROUP BY”在不存在聚集的情况下具有“DISTINCT”的效果。但是'DISTINCT'会偶然发现唯一的'id'。 –
在你的问题中提供'SHOW CREATE TABLE product_data'输出。 –
@kuldeepupadhyay请给我们每个指标组合时的结果,你mentionned –
@小宝答:是的,先生我的查询挑选他们查询花费1.0941秒 –