2017-09-29 76 views
0

什么是适合这个查询的索引。如何在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(productavailability

Key step_two(productavailabilitybrandstore

Key step_three(productavailabilitybrandstoreid

Key step_four(brandstore

Key step_five(brandstoreid

+1

在你的问题中提供'SHOW CREATE TABLE product_data'输出。 –

+1

@kuldeepupadhyay请给我们每个指标组合时的结果,你mentionned –

+0

@小宝答:是的,先生我的查询挑选他们查询花费1.0941秒 –

回答

1

真正的问题不是指数,而是防止服用LIMIT优势GROUP BYORDER BY之间的不匹配。

INDEX(product, availability, store, brand, id) 

将 “覆盖”,并以正确的顺序。但请注意,我已经换storebrand ......

更改查询

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)

+0

谢谢先生,我明白你的观点。 –

1

对于索引,最好索引是step_two。产品字段用于何处,并且与可用性字段相比具有更多的变体。

夫妇的关于查询注释:

  1. 可用性=“1”应该可用性=使得不必要内部 - > VARCHAR转换将避免1。
  2. “不应该将GROUP BY品牌”用作GROUP BY,只应在将聚合函数用作选定列时使用。你试图通过团队获得什么?
+0

是的先生我试过“SELECT ID,品牌”,但仍然使用tempory,使用filesort。请帮助 –

+0

你试图通过小组达成什么? – slaakso

1

如果没有聚合函数,你的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和临时表步骤,如果是这样的话 - 但我也不认为这些步骤应该是非常昂贵的。

+0

父亲请在这里检查http://sqlfiddle.com/#!9/5280b1/1 –

+1

这与原始请求不匹配,因为它无法执行“GROUP BY”。 –

+1

“GROUP BY”在不存在聚集的情况下具有“DISTINCT”的效果。但是'DISTINCT'会偶然发现唯一的'id'。 –

相关问题