今天刚刚测试了大型数据集。我的查询确实表现不佳,我怀疑是因为子查询。这是我的查询(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_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符号)及其日期戳
此表将记录data_list中仪器的每个结果。
table:data_list 的结果将在此表中记录:
[意向]
我想得到+ ve&amp;的总和 - 每种工具的每笔交易的价值:
IFNULL((SELECT SUM(trans_value * case trans_type when'1',然后是-1 else 1 end)FROM data_transaction_log WHERE trans_data_id = a.data_id和trans_type in('0','1')AND client_id =:client_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)
[问题}
在低数据集大约100(在data_transaction_log中)它可以正常工作。但是超过1k它真的很慢!
请指导我。
谢谢!
答案 0 :(得分:1)
对于data_list数据类型字段,多个值具有相同的精确结果。例如,WHEN a.data_type IN ('0', '1', '2', '3', '7', '9', '10', '12', '17')
你有相同的结果:
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)
我认为它不会使代码更快,但编写的代码更少,更容易调试:
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_transaction_log,再一步简单地算法一步,对于NULL ...主键不应为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