【问题标题】:how make this sql query faster如何使这个 sql 查询更快
【发布时间】: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


【解决方案1】:

没有为表定义索引。

问题.为了解决这个问题,我建议:

c:  INDEX(date_end, product_id,  price, customer_id, date_start)

当前编写的查询正在测试c.date_end >='2022-04-01' 两次。 (这不是性能问题。)

要进一步讨论,请回答以下问题:

  • 现在桌子有多大?
  • 是表ENGINE=InnoDB(应该是)。
  • `innodb_buffer_pool_size 的设置是什么?
  • 多少内存?

【讨论】:

  • 仅涉及 cus_pro_price 的 3 个表很大,有 490K 记录。其他只有数百行的表。我的mysql服务器只有3.23,我觉得应该是MyISAM。没有 InnoDB,所以没有设置 buffer_pool_size。通过 cat /proc/meminfo,我的系统总共有 cat /proc/meminfo:已使用:免费:内存:1038528512 16424960 交换:2146787328 23691264 2123096064
  • 哎呀! 4.0 出现在 2 多年前;那是添加 InnoDB 的时候。稍等片刻,我在一堆打孔卡中寻找 MyISAM。
  • key_buffer_size的设置是什么?
  • 等等...您在问题中说“MySQL 5.5.62”,但现在您说的是“3.23”???
  • 结果有多少行?只有 1GB 的 RAM,我怀疑它无法保持足够快的缓存数据。我建议的索引应该会有所帮助,也许就足够了。使用较小的数字数据类型(在可行的情况下)会有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 2014-11-29
  • 1970-01-01
相关资源
最近更新 更多