Mysql 为什么我的sql查询速度慢?
我尝试创建一个从4个表(tb_用户为200行,tb_事务为250.000行,tb_事务为250.000行,tb_ms_位置为50行)连接的视图, 当我使用datatables服务器端渲染时,需要13秒。即使我过滤它 我不知道为什么要花太长时间 这里是我的sql查询Mysql 为什么我的sql查询速度慢?,mysql,sql,Mysql,Sql,我尝试创建一个从4个表(tb_用户为200行,tb_事务为250.000行,tb_事务为250.000行,tb_ms_位置为50行)连接的视图, 当我使用datatables服务器端渲染时,需要13秒。即使我过滤它 我不知道为什么要花太长时间 这里是我的sql查询 CREATE VIEW `vw_cashback` AS SELECT `tb_user`.`nik` AS `nik`, `tb_user`.`full_name` AS `nam
CREATE VIEW `vw_cashback` AS
SELECT
`tb_user`.`nik` AS `nik`,
`tb_user`.`full_name` AS `nama`,
`tb_ms_location`.`location_name` AS `lokasi`,
`tb_transaction`.`date_transaction` AS `tanggal_setor`,
sum(CASE WHEN `tb_transaction_detail`.`vehicle_type`=1 THEN 1 ELSE 0 END) AS `mobil`,
sum(CASE WHEN `tb_transaction_detail`.`vehicle_type`=2 THEN 1 ELSE 0 END) AS `motor`,
sum(CASE WHEN `tb_transaction_detail`.`vehicle_type`=3 THEN 1 ELSE 0 END) AS `truck`,
sum(CASE WHEN `tb_transaction_detail`.`vehicle_type`=4 THEN 1 ELSE 0 END) AS `speda`,
sum(`tb_transaction_detail`.`total`) AS `total_global`,
(sum(`tb_transaction_detail`.`total`) * 0.8) AS `total_user`,
(sum(`tb_transaction_detail`.`total`) * 0.2) AS `total_tgr`,
((sum(`tb_transaction_detail`.`total`) * 0.2) / 2) AS `total_cashback`,
(curdate() - cast(`tb_user`.`created_at` AS date)) AS `status`
FROM `tb_user`
JOIN `tb_transaction` ON `tb_user`.`id` = `tb_transaction`.`user_id`
JOIN `tb_transaction_detail` ON `tb_transaction`.`id` = `tb_transaction_detail`.`transaction_id`
JOIN `tb_ms_location` ON `tb_ms_location`.`id` = `tb_transaction`.`location_id`
GROUP BY
`tb_user`.`id`,
`tb_transaction`.`date_transaction`,
`tb_user`.`nik`,
`tb_user`.`full_name`,
`tb_user`.`created_at`,
`tb_ms_location`.`location_name`
谢谢未筛选的查询一定会很慢,因为它会从所有表中获取所有记录,并对它们进行连接和聚合 但是你说当你过滤时,视图仍然很慢。问题是:如何过滤?当您按用户、位置和交易日期进行聚合时,它应该是其中之一。但是,结果列表中没有用户ID或事务ID。这感觉不自然,我建议您添加它们,因此
select * from vw_cashback where user_id = 5
或
这是可能的
按原样,您必须按位置名称或用户nik/name进行筛选。因此,如果需要,请为查找创建索引:
CREATE idx_location_name ON tb_ms_location(location_name, id)
CREATE idx_user_name ON tb_user(full_name, id)
CREATE idx_user_nik ON tb_user(nik, id)
后两者甚至可以转化为覆盖索引(即包含查询中使用的所有列的索引),这仍然可以加快过程:
CREATE idx_user_name ON tb_user(nik, id, full_name, created_at);
CREATE idx_user_nik ON tb_user(full_name, id, nik, created_at);
至于通过索引的访问,您可能还需要覆盖索引:
CREATE idx_location_id ON tb_ms_location(id, location_name)
CREATE idx_user_id ON tb_user(id, nik, full_name, created_at);
使用数据库的“解释”功能让它告诉您如何优化查询。我使用mysql作为我的数据库,我的数据大吗?在联接中使用的所有列上都有索引吗?它不是特别大。但是,如果查询和/或模式经过良好设计和适当优化,数据库应该能够查询大型表。因此。。。使用“解释”。寻求调试帮助的问题(“为什么此代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现这些问题所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建一个最小、完整且可验证的示例。
CREATE idx_location_id ON tb_ms_location(id, location_name)
CREATE idx_user_id ON tb_user(id, nik, full_name, created_at);