【发布时间】:2022-11-02 18:26:41
【问题描述】:
我有一个关于 mysql 的查询,最终运行速度非常慢。查询如下。
select v.product_id, v.product_name, c.price,c.customer_id,
n.customer_name, date_start, date_end
from vol_product v
left outer join cus_pro_price c on v.product_id=c.product_id
left outer join ntt_customer n on n.customer_id=c.customer_id
where v.status!='110' and date_end >='2022-04-01'
and date_end between '2022-04-01' and '2022-10-31'
此查询在已运行 10 多年的应用程序中运行。当表很小时,最初没有性能问题。
MySQL 3.23
SQL查询:描述vol_product;
Field Type Null Key Default Extra
product_name varchar(50) NO
product_unit_id varchar(4) NO
status int(11) NO 0
product_id int(11) NO PRI NULL auto_increment
sort_order int(11) NO 0
quo_price double(16,4) NO 0.0000
SQL查询:描述ntt_customer;
Field Type Null Key Default Extra
customer_id int(11) unsigned NO PRI NULL auto_increment
customer_name varchar(50) NO
country_id char(2) NO h
address varchar(80) YES NULL
tel varchar(20) NO
fax varchar(20) YES NULL
credit_limit double(16,4) unsigned YES NULL
credit_balance double(16,4) unsigned YES NULL
day_allowance int(11) unsigned NO 30
status_id int(11) NO 0
official_name varchar(50) NO
customer_no varchar(20) NO
line_no int(11) NO 80
SQL 查询:描述 cus_pro_price;
Field Type Null Key Default Extra
id int(10) NO PRI NULL auto_increment
customer_id int(11) NO MUL 0
product_id int(11) NO 0
price double(16,2) NO 0.00
date_start date NO 0000-00-00
date_end date YES 0000-00-00
date_add datetime YES 0000-00-00 00:00:00
autostatus enum('0','1') NO 0
没有为表定义索引。
但现在桌子大小:
vol_product ~400
ntt_customer ~400
cus_pro_price ~480,000
cus_pro_price 是与时间相关的数据,因此有一个 date_end 和 date_created 字段。
实际上,在 cus_pro_price 的 480,000 行中,只有大约 16000 行对此查询感兴趣,我实际上可以通过 date_end(before_date 和 limit_date)之间的行来缩小行数。
我认为现在上面的查询是在加入后按日期过滤的,你认为如果我可以在加入前过滤日期,会更快吗?如何?
谢谢。
【问题讨论】:
-
请包括您的表架构和现有索引。为什么
date_end上有多余的子句? -
和一个有效的查询!
-
请您阅读Tips for asking a good Structured Query Language (SQL) question) 并相应地修改您的问题。
-
而不是
describe <tablename>使用SHOW CREATE TABLE <tablename>。这将返回包括所有索引的创建语句。 -
“这可能是一个错误” - 然后先修复它。
标签: mysql join query-optimization