Mysql查询真的很慢

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

今天刚刚用大型数据集进行了测试。而且我的查询执行得很差,我怀疑是因为子查询。以下是我的查询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符号和日期戳

表:数据\事务\日志 此表将记录数据列表中仪器的所有结果

表的结果:数据列表将记录在此表中:

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,我不知道要编制什么索引,因为数据可能重复,但唯一唯一的是日期戳。