Mysql查询真的很慢
今天刚刚用大型数据集进行了测试。而且我的查询执行得很差,我怀疑是因为子查询。以下是我的查询MYSQL PDO:Mysql查询真的很慢,mysql,sql,Mysql,Sql,今天刚刚用大型数据集进行了测试。而且我的查询执行得很差,我怀疑是因为子查询。以下是我的查询MYSQL PDO: SELECT a.data_id,a.data_name,a.data_parent_id,a.data_type,a.data_return_text,a.data_description, IF ((length(a.data_id)<=1), 0, CASE a.data_type WHEN '0' THEN IFNULL((SELECT SUM(trans_valu
SELECT a.data_id,a.data_name,a.data_parent_id,a.data_type,a.data_return_text,a.data_description,
IF ((length(a.data_id)<=1), 0,
CASE a.data_type
WHEN '0'
THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '1' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('0','1') AND client_id=:client_id),0)
WHEN '1' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '1' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('0','1') AND client_id=:client_id),0)
WHEN '2' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '1' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('0','1') AND client_id=:client_id),0)
WHEN '3' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '1' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('0','1') AND client_id=:client_id),0)
WHEN '4' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '0' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('1','0') AND client_id=:client_id),0)
WHEN '5' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '0' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('1','0') AND client_id=:client_id),0)
WHEN '6' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '0' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('1','0') AND client_id=:client_id),0)
WHEN '7' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '1' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('0','1') AND client_id=:client_id),0)
WHEN '8' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '0' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('1','0') AND client_id=:client_id),0)
WHEN '9' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '1' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('0','1') AND client_id=:client_id),0)
WHEN '10' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '1' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('0','1') AND client_id=:client_id),0)
WHEN '11' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '0' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('1','0') AND client_id=:client_id),0)
WHEN '12' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '1' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('0','1') AND client_id=:client_id),0)
WHEN '13' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '0' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('1','0') AND client_id=:client_id),0)
WHEN '14' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '0' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('1','0') AND client_id=:client_id),0)
WHEN '15' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '0' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('1','0') AND (DATE(trans_date) <= DATE(NOW())) AND client_id=:client_id),0)
WHEN '16' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '1' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('0','1') AND (DATE(trans_date) <= DATE(NOW())) AND client_id=:client_id),0)
WHEN '17' THEN
IFNULL((SELECT SUM(trans_value * case trans_type when '1' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('0','1') AND client_id=:client_id),0)
END) as total
FROM data_list a
LEFT JOIN data_transaction_log b
ON b.trans_data_id = a.data_id
WHERE a.client_id=:client_id
GROUP BY a.data_name
ORDER BY a.data_id asc
[说明]
有一张桌子:
表:数据列表
包含大约24个工具,这些工具在使用时将创建事务日志。它将产生一个值及其+ve或-ve符号和日期戳
表:数据\事务\日志
此表将记录数据列表中仪器的所有结果
表的结果:数据列表将记录在此表中:
value=>trans_值
+ve符号将记录为0&-ve符号将记录为1=>trans\u类型
日期=>trans_日期
[意图]
我想获得每个工具的每笔交易的+ve和-ve值之和:
如果为空,则在“1”时选择SUMtrans_值*case trans_类型,然后从数据\u事务\u日志中选择-1 else 1结束,其中trans_数据\u id=a。数据\u id和trans_类型在“0”中,'1'和客户端\u id=:客户端\u id,0
有些仪器有特殊条件,如15和16,需要日期条件
IFNULL((SELECT SUM(trans_value * case trans_type when '1' then -1 else 1 end) FROM data_transaction_log WHERE trans_data_id = a.data_id and trans_type in ('0','1') AND (DATE(trans_date) <= DATE(NOW())) AND client_id=:client_id),0)
[问题]
在低数据集上,在数据\u事务\u日志中大约有100个,它工作正常。但是超过1k,它真的很慢
请引导我
谢谢!对于数据列表数据类型字段,对于多个值都有相同的精确结果。例如,当a.data\u键入“0”、“1”、“2”、“3”、“7”、“9”、“10”、“12”、“17” 您得到了相同的结果: 如果为空,则在“1”时选择SUMtrans_值*case trans_类型,然后从数据\u事务\u日志中选择-1 else 1结束,其中trans_数据\u id=a。数据\u id和trans_类型在“0”中,'1'和客户端\u id=:客户端\u id,0 我不认为这会使代码更快,但编写的代码更少,调试也更容易:
SELECT a.data_id,a.data_name,a.data_parent_id,a.data_type
,a.data_return_text,a.data_description
,CASE WHEN length(a.data_id)<=1)
THEN 0
WHEN a.data_type IN ('0', '1', '2', '3', '7', '9', '10', '12', '17')
THEN IFNULL((SELECT SUM(trans_value * case WHEN trans_type = '1' THEN -1 else 1 end)
FROM data_transaction_log
WHERE trans_data_id = a.data_id and trans_type in ('0','1')
AND client_id=:client_id)
,0)
WHEN a.data_type IN ('4', '5', '6', '8', '11', '13', '14')
THEN IFNULL((SELECT SUM(trans_value * case WHEN trans_type = '0' then -1 else 1 end)
FROM data_transaction_log
WHERE trans_data_id = a.data_id and trans_type in ('0','1')
AND client_id=:client_id)
,0)
WHEN a.data_type IN ('15', '16')
THEN IFNULL((SELECT SUM(trans_value * case WHEN trans_type = '0' then -1 else 1 end)
FROM data_transaction_log
WHERE trans_data_id = a.data_id and trans_type in ('0','1')
AND (DATE(trans_date) <= DATE(NOW())) AND client_id=:client_id)
,0)
END as total
FROM data_list a LEFT JOIN data_transaction_log b ON b.trans_data_id = a.data_id
WHERE a.client_id=:client_id
GROUP BY a.data_name
ORDER BY a.data_id asc
-
第二步:
要进一步研究这个问题,最好知道为什么要检查IFNULL。如果是因为左连接返回NULL,而连接条件不匹配,那么您可以通过检查左连接表data\u transaction\u log中的主键是否为NULL,将算法简化一步……主键应该not be null,如果为null,则通过左连接必须为null。在原始算法中,您为null结果提供了0值:
SELECT a.data_id,a.data_name,a.data_parent_id,a.data_type
,a.data_return_text,a.data_description
,CASE WHEN b.<PRIMARYKEY> IS NULL
THEN 0
WHEN length(a.data_id)<=1)
THEN 0
WHEN a.data_type IN ('0', '1', '2', '3', '7', '9', '10', '12', '17')
THEN (SELECT SUM(trans_value * case WHEN trans_type = '1' THEN -1 else 1 end)
FROM data_transaction_log
WHERE trans_data_id = a.data_id and trans_type in ('0','1') AND client_id=:client_id)
WHEN a.data_type IN ('4', '5', '6', '8', '11', '13', '14')
THEN (SELECT SUM(trans_value * case WHEN trans_type = '0' then -1 else 1 end)
FROM data_transaction_log
WHERE trans_data_id = a.data_id and trans_type in ('0','1')
AND client_id=:client_id)
WHEN a.data_type IN ('15', '16')
THEN (SELECT SUM(trans_value * case WHEN trans_type = '0' then -1 else 1 end)
FROM data_transaction_log
WHERE trans_data_id = a.data_id and trans_type in ('0','1')
AND (DATE(trans_date) <= DATE(NOW())) AND client_id=:client_id)
END as total
FROM data_list a LEFT JOIN data_transaction_log b ON b.trans_data_id = a.data_id
WHERE a.client_id=:client_id
GROUP BY a.data_name
ORDER BY a.data_id asc
您尝试过为任何列编制索引吗?对于索引,表:data\u list我为其data\u id编制了索引,但是对于表:data\u transaction\u log,我不知道要编制什么索引,因为数据可能重复,但唯一唯一的是日期戳。