这是我想要优化的查询:
SELECT SUM(`backend_ubqstat`.`complementary_revenue`) AS `complementary_revenue__sum`, SUM(`backend_ubqstat`.`revenue`) AS `revenue__sum` FROM `backend_ubqstat`
INNER JOIN `backend_ubq` ON ( `backend_ubqstat`.`ubq_id` = `backend_ubq`.`id` )
WHERE
(`backend_ubqstat`.`store_number` = 389 AND (`backend_ubqstat`.`week_of_year` = 2 OR `backend_ubqstat`.`week_of_year` = 3)
AND (`backend_ubq`.`department` = 'QUINCAILLERIE' OR `backend_ubq`.`department` = 'OUTILLAGE')
AND (`backend_ubq`.`sub_department` = 'Outillage à moteur' OR `backend_ubq`.`sub_department` = 'Outillage à main' OR `backend_ubq`.`sub_department` = 'Outil d\'assemblage'));
此查询需要73秒才能执行。只有一周的同一查询(backend_ubqstat
。week_of_year
= 2,没有OR):
SELECT SUM(`backend_ubqstat`.`complementary_revenue`) AS `complementary_revenue__sum`, SUM(`backend_ubqstat`.`revenue`) AS `revenue__sum` FROM `backend_ubqstat`
INNER JOIN `backend_ubq` ON ( `backend_ubqstat`.`ubq_id` = `backend_ubq`.`id` )
WHERE
(`backend_ubqstat`.`store_number` = 389 AND (`backend_ubqstat`.`week_of_year` = 2)
AND (`backend_ubq`.`department` = 'QUINCAILLERIE' OR `backend_ubq`.`department` = 'OUTILLAGE')
AND (`backend_ubq`.`sub_department` = 'Outillage à moteur' OR `backend_ubq`.`sub_department` = 'Outillage à main' OR `backend_ubq`.`sub_department` = 'Outil d\'assemblage'));
需要0.1秒才能执行。我试图了解第一个查询的主要问题是什么。
此查询计算特定商店中某些产品在一周内的收入总和。
我使用这些结果在两个查询上运行了EXPLAIN:
多周(第一次查询):
+----+-------------+-----------------+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+---------+------------------------------------+------+------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------------+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+---------+------------------------------------+------+------------------------------------+
| 1 | SIMPLE | backend_ubqstat | range | backend_ubq_store_number_4ba08aefde7a0fdc_uniq,backend_ubq_ubq_id_2883f2962b976ce1_uniq,backend_ubq_week_of_year_534972be244e06dd_uniq,backend_ubqstat_week_of_year_1f3b84a6cf9999f7_idx | backend_ubqstat_week_of_year_1f3b84a6cf9999f7_idx | 4 | NULL | 2975 | Using index condition; Using where |
| 1 | SIMPLE | backend_ubq | eq_ref | PRIMARY,backend_ubq_department_2cef48a6c5825cef_uniq,backend_ubq_sub_department_65793aef847267e8_uniq,backend_ubq_department_2ebadbdc749719ff_idx | PRIMARY | 4 | xxxxxxxxxxx.backend_ubqstat.ubq_id | 1 | Using where |
+----+-------------+-----------------+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+---------+------------------------------------+------+------------------------------------+
仅限一周(第二次查询):
+----+-------------+-----------------+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+---------+------------------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------------+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+---------+------------------------------------+------+-------------+
| 1 | SIMPLE | backend_ubqstat | ref | backend_ubq_store_number_4ba08aefde7a0fdc_uniq,backend_ubq_ubq_id_2883f2962b976ce1_uniq,backend_ubq_week_of_year_534972be244e06dd_uniq,backend_ubqstat_week_of_year_1f3b84a6cf9999f7_idx | backend_ubqstat_week_of_year_1f3b84a6cf9999f7_idx | 4 | const,const | 1475 | Using where |
| 1 | SIMPLE | backend_ubq | eq_ref | PRIMARY,backend_ubq_department_2cef48a6c5825cef_uniq,backend_ubq_sub_department_65793aef847267e8_uniq,backend_ubq_department_2ebadbdc749719ff_idx | PRIMARY | 4 | xxxxxxxxx.backend_ubqstat.ubq_id | 1 | Using where |
+----+-------------+-----------------+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+---------+------------------------------------+------+-------------+
这些是两个表的架构: 产品表: MySQL的>描述backend_ubq;
+----------------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| ub | varchar(30) | NO | | NULL | |
| department | varchar(30) | NO | MUL | NULL | |
| sub_department | varchar(50) | NO | MUL | NULL | |
| family | varchar(50) | NO | MUL | NULL | |
| sub_family_id | smallint(5) unsigned | NO | | NULL | |
| sub_family | varchar(50) | NO | MUL | NULL | |
| brand | varchar(50) | NO | MUL | NULL | |
| quartile | smallint(5) unsigned | NO | MUL | NULL | |
+----------------+----------------------+------+-----+---------+----------------+
此表有3604行。
按产品编号和商店编号划分的每种产品的收入表: MySQL的>描述backend_ubqstat;
+-----------------------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| ubq_id | int(11) | YES | MUL | NULL | |
| week_of_year | smallint(5) unsigned | NO | MUL | NULL | |
| month_of_year | smallint(5) unsigned | NO | | NULL | |
| year | smallint(5) unsigned | NO | MUL | NULL | |
| store_number | smallint(5) unsigned | NO | MUL | NULL | |
| nb_tickets | smallint(5) unsigned | NO | | NULL | |
| nb_items | smallint(5) unsigned | NO | | NULL | |
| revenue | decimal(9,2) | NO | | NULL | |
| complementary_revenue | decimal(9,2) | NO | | NULL | |
+-----------------------+----------------------+------+-----+---------+----------------+
此表有20 832 730行。
我正在使用MySQL 5.6。
我做了一些研究,但我无法找到解决问题的方法。我需要做些什么才能使第一个查询运行得更快?
答案 0 :(得分:0)
当列被编入索引并使用OR
时,优化器将无法使用索引。对于您的情况,如果列week_of_year
未编入索引,那么您可以索引此列。现在要解决此问题,您可以使用UNION
并将OR
条件移动为2个不同的查询,如下所示。尝试使用Explain
,看看你得到了什么。
SELECT
SUM(`backend_ubqstat`.`complementary_revenue`) AS `complementary_revenue__sum`,
SUM(`backend_ubqstat`.`revenue`) AS `revenue__sum`
FROM `backend_ubqstat`
INNER JOIN `backend_ubq` ON ( `backend_ubqstat`.`ubq_id` = `backend_ubq`.`id` )
WHERE
(
`backend_ubqstat`.`store_number` = 389 AND `backend_ubqstat`.`week_of_year` = 2
AND (`backend_ubq`.`department` = 'QUINCAILLERIE' OR `backend_ubq`.`department` = 'OUTILLAGE')
AND (`backend_ubq`.`sub_department` = 'Outillage à moteur' OR `backend_ubq`.`sub_department` = 'Outillage à main' OR `backend_ubq`.`sub_department` = 'Outil d\'assemblage')
)
union
SELECT
SUM(`backend_ubqstat`.`complementary_revenue`) AS `complementary_revenue__sum`,
SUM(`backend_ubqstat`.`revenue`) AS `revenue__sum`
FROM `backend_ubqstat`
INNER JOIN `backend_ubq` ON ( `backend_ubqstat`.`ubq_id` = `backend_ubq`.`id` )
WHERE
(
`backend_ubqstat`.`store_number` = 389 AND `backend_ubqstat`.`week_of_year` = 3
AND (`backend_ubq`.`department` = 'QUINCAILLERIE' OR `backend_ubq`.`department` = 'OUTILLAGE')
AND (`backend_ubq`.`sub_department` = 'Outillage à moteur' OR `backend_ubq`.`sub_department` = 'Outillage à main' OR `backend_ubq`.`sub_department` = 'Outil d\'assemblage')
)