Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何替换WHERE子句中的WHERE IN选项以减少请求的执行时间?_Mysql_Query Optimization_Unidac - Fatal编程技术网

Mysql 如何替换WHERE子句中的WHERE IN选项以减少请求的执行时间?

Mysql 如何替换WHERE子句中的WHERE IN选项以减少请求的执行时间?,mysql,query-optimization,unidac,Mysql,Query Optimization,Unidac,我在东京RAD Studio 10.2上写的C++项目中使用DBF数据库。为了对这个数据库发出请求,我使用UniDac Devart组件(与MySQL本身相比有点有限)。我遇到的问题是,在请求中使用WHERE-IN条件时,请求的执行时间太长(有时超过一个小时) 这是我的要求: SELECT accountrp, SUM(amounteur) AS montant FROM %s WHERE doctype='1' AND period<>'00' AND matchno IN(SE

我在东京RAD Studio 10.2上写的C++项目中使用DBF数据库。为了对这个数据库发出请求,我使用UniDac Devart组件(与MySQL本身相比有点有限)。我遇到的问题是,在请求中使用WHERE-IN条件时,请求的执行时间太长(有时超过一个小时)

这是我的要求:

SELECT accountrp, SUM(amounteur) AS montant FROM %s 
WHERE doctype='1' AND period<>'00' AND
matchno IN(SELECT matchno FROM %s GROUP BY matchno HAVING SUM(amounteur)<>0)
GROUP BY accountrp
从%s中选择accountrp,总和(amountur)作为montant
其中doctype='1'和句点'00'和
中的匹配号(按总和(数量)为0的匹配号从%s组中选择匹配号)
按帐户分组
accountrp、doctype、句点为字符,数量为数字

问题就出在matchno这条线上。我想在不使用的情况下优化请求。我在互联网上看到,在条件的地方可以用内部连接连接代替,但我不知道这是否是解决方案,以及如何做到这一点

你能帮帮我吗

您可以尝试使用下面的

SELECT s.accountrp, SUM(s.amounteur) AS montant FROM %s s
  join 
   (SELECT matchno FROM %s GROUP BY matchno HAVING SUM(amounteur)<>0) t
  on s.matchno =t.matchno
WHERE s.doctype='1' AND s.period<>'00'
GROUP BY s.accountrp
从%s中选择s.accountrp,SUM(s.amountur)作为蒙塔特
参加
(按总和(数量)为0的匹配号从%s组中选择匹配号)
关于s.matchno=t.matchno
其中s.doctype='1'和s.period'00'
按s.accountrp分组
第一个建议 您可以更改内部联接中的IN子句
这对性能来说应该更有效

SELECT accountrp, 
    SUM(amounteur) AS montant 
FROM %s  as s 
INNER JOIN  ( 
  SELECT matchno 
  FROM %s 
  GROUP BY matchno 
  HAVING SUM(amounteur)<>0
) t on t.matchno = s.matchno
WHERE doctype='1' AND period<>'00' AND
GROUP BY accountrp
选择accountrp,
以蒙塔特计算的金额
从%s作为%s
内连接(
选择匹配号
来自%s
按匹配号分组
总和(数量)为0的
)t在t.matchno上=s.matchno
其中doctype='1'和句点'00'和
按帐户分组

这是因为In子句相当于一组OR条件,并且每次对每个OR执行查询。。内部连接只是两个表之间的连接,只执行一次

看起来非常快!内部连接和连接是一样的,你认为呢?是的,内部连接和连接是一样的。但是更明确,更容易理解read@development您需要的所有测试..但IN子句和联接之间的差异不会改变。。您需要检查两种方法在性能上的差异是否基于结果中元素的数量…元素越多,时间上的差异越大..并且在类别中超过一定数量的元素时,会产生错误,因为由in管理的元素数量有限制clause@scaisEdge在MySQL 5.6及更高版本中,子查询只能执行一次,结果存储在临时表中。使您的查询更快的可能是这个临时表将是join中的第一个表。这样,将只读取具有相关匹配号的行,而不是读取表s的所有行。@oysteing。您可以尝试更改嵌套子查询的顺序,您可以看到subselect上的内部joion总是比同一子查询上的IN子句快。。这是一个简单的概念。IN子句的每个结果值都意味着在相关表中扫描该值。。(作为或条款)。。对于联接,查询的结果集本身就是一个表,这些值之间的关系只扫描一次。。表在查询中的位置是由查询优化管理的,并且可能会受到影响,但以一种复杂的方式进行管理,这永远都不方便