2013-01-07 178 views
0

我有一个使用group by和order by的查询,但速度很慢!我需要一些帮助才能使索引正确。这是我在运行查询:MYSQL查询速度很慢,使用group by by

select * 
    from puresen_mv_shop.cache_deals 
where feature_ids REGEXP 'i,t,d' 
and phone_cost > 100.00 
group by handset_numeric_id 
order by popularity 
LIMIT 0,10; 

解释:

1 SIMPLE cache_deals index  popularity 5  10 6635320.00 Using where; Using temporary 

这运行在约3秒,但我需要它第二次下。表中有超过60万行。下面是表的结构:

mysql> describe cache_deals 
     -> ; 
    +-------------------------+---------------+------+-----+---------+-------+ 
    | Field     | Type   | Null | Key | Default | Extra | 
    +-------------------------+---------------+------+-----+---------+-------+ 
    | deal_id     | varchar(100) | NO |  | NULL |  | 
    | deal_id_replication  | varchar(150) | NO | PRI |   |  | 
    | handset_numeric_id  | int(10)  | YES | MUL | NULL |  | 
    | handset_url    | varchar(100) | YES |  | NULL |  | 
    | image_url    | varchar(50) | YES | MUL | NULL |  | 
    | handset_id    | varchar(50) | YES |  | NULL |  | 
    | phone_cost    | decimal(10,2) | YES |  | NULL |  | 
    | tariff_numeric_id  | int(10)  | YES | MUL | NULL |  | 
    | tariff_id    | varchar(100) | YES | MUL | NULL |  | 
    | tariff_name    | varchar(100) | YES |  | NULL |  | 
    | network_name   | varchar(20) | YES |  | NULL |  | 
    | network_numeric_id  | int(5)  | YES | MUL | NULL |  | 
    | term     | int(5)  | YES | MUL | NULL |  | 
    | minutes     | int(5)  | YES | MUL | NULL |  | 
    | texts     | int(5)  | YES | MUL | NULL |  | 
    | data     | int(5)  | YES | MUL | NULL |  | 
    | org_line_rental   | decimal(10,2) | YES | MUL | NULL |  | 
    | effective_monthly_cost | decimal(10,2) | YES | MUL | NULL |  | 
    | free_gift_id   | int(10)  | YES | MUL | NULL |  | 
    | free_gift_name   | varchar(50) | YES |  | NULL |  | 
    | cashback    | int(5)  | YES | MUL | NULL |  | 
    | free_lr     | int(5)  | YES | MUL | NULL |  | 
    | half_lr     | int(5)  | YES | MUL | NULL |  | 
    | clearance_flag   | int(5)  | YES | MUL | NULL |  | 
    | manufacturer_numeric_id | int(5)  | YES | MUL | NULL |  | 
    | manufacturer_name  | varchar(50) | YES |  | NULL |  | 
    | full_handset_name  | varchar(100) | YES |  | NULL |  | 
    | popularity    | int(20)  | YES | MUL | NULL |  | 
    | handset_colour   | varchar(50) | YES | MUL | NULL |  | 
    | feature_ids    | varchar(100) | YES |  | NULL |  | 
    | operating_system  | varchar(30) | YES | MUL | NULL |  | 
    +-------------------------+---------------+------+-----+---------+-------+ 

这里是目前我已经有了这个表上的索引:

mysql> show index from cache_deals; 
+-------------+------------+-------------------------+--------------+-------------------------+-----------+-------------+----------+--------+------+------------ 
| Table  | Non_unique | Key_name    | Seq_in_index | Column_name    | Collation | Cardinality | Sub_part | Packed | Null | Index_type 
+-------------+------------+-------------------------+--------------+-------------------------+-----------+-------------+----------+--------+------+------------ 
| cache_deals |   0 | PRIMARY     |   1 | deal_id_replication  | A   |  663532 |  NULL | NULL |  | BTREE 
|   |    | 
| cache_deals |   1 | handset_numeric_id  |   1 | handset_numeric_id  | A   |   759 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | network_numeric_id  |   1 | network_numeric_id  | A   |   8 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | tariff_numeric_id  |   1 | tariff_numeric_id  | A   |  1091 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | manufacturer_numeric_id |   1 | manufacturer_numeric_id | A   |   23 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | operating_system  |   1 | operating_system  | A   |   42 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | image_url    |   1 | image_url    | A   |   755 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | tariff_id    |   1 | tariff_id   | A   |  1091 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | term     |   1 | term   | A   |   7 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | minutes     |   1 | minutes     | A   |   26 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | texts     |   1 | texts     | A   |   14 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | data     |   1 | data     | A   |   14 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | org_line_rental   |   1 | org_line_rental   | A   |   128 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | effective_monthly_cost |   1 | effective_monthly_cost | A   |  2147 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | free_gift_id   |   1 | free_gift_id   | A   |   105 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | cashback    |   1 | cashback    | A   |   2 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | free_lr     |   1 | free_lr     | A   |   2 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | half_lr     |   1 | half_lr     | A   |   2 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | clearance_flag   |   1 | clearance_flag   | A   |   2 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | handset_colour   |   1 | handset_colour   | A   |   17 |  NULL | NULL | YES | BTREE 
|   |    | 
| cache_deals |   1 | popularity    |   1 | popularity    | A   |   718 |  NULL | NULL | YES | BTREE 
|   |    | 
+-------------+------------+-------------------------+--------------+-------------------------+-----------+-------------+----------+--------+------+------------ 

我是不是正确索引这个表?

感谢您的帮助。

回答

3

REGEXP由于无法使用索引而导致潜在性能下降。查询的这一部分可以用其他方式编写或可以标准化为另一个表?如果可以的话,那可能会有所帮助。除此之外,phone_costhandset_numeric_id上的复合索引应该有所帮助。同时将popularity添加到该索引可能会有所帮助,但是MySQL已经对查询不满意,因为您实际上不应该能够使用不在GROUP BY子句中的列。

作为附注,列的数据类型可能更有效。 int(5)由于INT的限制,与MEDIUMINT的作用相同,只是MEDIUMINT小一个字节。另外,int(20)没有意义,因为INT类型不能那么大。

0
select [name the columns you actually want returned] 
     from puresen_mv_shop.cache_deals 
    where feature_ids = 'i,t,d' 
     and phone_cost > 100.00 
    order 
     by popularity 
    LIMIT 0,10; 

指数features_id或(features_id,phone_cost)

+0

'REGEXP'是不一样的'='和不能利用索引。 –

+0

我需要群组,因为我需要为每个手机ID返回一笔交易。我正在使用REGEXP,因为feature_id字段需要匹配多个字母,并且每个手机可能在该字段中具有多达15个功能。 –