首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL不是IN (array[])还是PHP in_array(array[])?

MySQL不是IN (array[])还是PHP in_array(array[])?
EN

Stack Overflow用户
提问于 2022-01-01 08:24:16
回答 3查看 132关注 0票数 0

我有一个每小时运行一次的查询,我正在处理这个查询中的某个数据集。在处理这个数据集时,我需要忽略一些is,我目前正在使用NOT IN进行此操作,但是我需要忽略的is数量大约是50个。

我想知道的问题是,我用正在处理的数据以某种模式创建一个文本文件,是直接在查询中使用这个忽略操作,还是在foreach模式中使用这个忽略操作,以获得更好的性能?

查询返回由10米记录组成的数据集中的大约5000-7000个数据,我需要忽略结果集.中的大约50个ID。

让我们说;

代码语言:javascript
复制
$blacklist_arr = array(1,10,20,30,40,50,60,70,80,90,100); //around 50 element in array~

我现在用的东西;

代码语言:javascript
复制
...QUERY...
resultSet.ID NOT IN (\'' . implode( "', '" , $blacklist_arr ) . '\')

我打算用的东西;

代码语言:javascript
复制
foreach ($final_dataset as $final_data) {
    ...
    if (!in_array($final_data, $blacklist_arr )) {
    //write to file
    ...

编辑*查询结构如下;

代码语言:javascript
复制
SELECT * 
FROM
    (
        (
        SELECT DISTINCT a.col1, a.col2, a.col3, a.col4,..., a.coln
        FROM
            `a`
            INNER JOIN ( SELECT MAX( b.col4 ) AS X, b.col2 FROM `a` AS `b` GROUP BY b.col2 ORDER BY NULL ) sub ON ( sub.X = a.col4 ) 
        WHERE
            ( a.someColumn > NOW( ) - INTERVAL 2 HOUR ) 
            AND ( a.col3 < DATE_HERE ) 
        ) UNION
        (
        SELECT  a.col1, a.col2, a.col3, a.col4,..., a.coln
        FROM
            `a` 
        WHERE
            ( a.someColumn >= DATE_SUB( NOW( ), INTERVAL 3 MONTH ) AND a.col4 IS NULL ) 
            AND ( a.col3 < DATE_HERE ) 
        ) 
    ) AS resultSet 
WHERE
    resultSet.col1 NOT IN ( 1,10,20,30,40,50,60,70,80,90,100 ) 
ORDER BY
    resultSet.col3 ASC,
    resultSet.col2 ASC,
    resultSet.col4 ASC,
    resultSet.col1 DESC
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-01-01 16:23:21

有以下几点:

  • I有一个“经验法则”:“如果一个可能的优化方案被估计能改善10%以下的事情,那就继续前进。也就是说,不要在这上面花费额外的努力。相反,要寻找一些更好的东西去做。”根据您的数字,优化只使结果集减少约1%。

  • 有一个标准的编程规则:“接吻”。哪个代码更简单-- NOT IN还是PHP?一个变体:“哪种方法是较少的击键?”这来源于“程序员的时间比计算机时间更有价值。”

  • NOT IN移动到每个子查询中,可能会稍微加快速度。这是因为它会减少(稍微)查询所涉及的中间表。(然而,这不符合10%的接吻规则。)另一方面,它可以消除最外层的选择。注:此操作:(SELECT ...) UNION (SELECT ...) ORDER BY....

  • 潜在错误:最内部的选择可能是从排除的Col1的.

中选择一个日期和时间。

  • UNION默认为UNION DISTINCT,这比UNION ALL慢。把这看作是一个更大的optimization.

  • ON ( sub.X = a.col4)可能需要提到col2.

  • DATE_HERENOW()有某种联系吗?也许你需要TIMESTAMP而不是DATETIME,反之亦然?

  • 我怀疑DISTINCT是不需要的。无论如何,它与UNION.

是冗余的。

  • 考虑“黑名单”是否应该是表,而不是配置文件。作为表,需要将NOT EXISTS(..)LEFT JOIN .. IS NOT NULL添加到查询中。这将比现在的速度慢,但可能“更干净”。

  • WHERE 1=1是懒惰编程的产物;它不是优化;优化器只会简单地抛出它。

  • 通常,更好的索引提供了最大的改进。也许以下几点会有帮助。注意:单独的单列索引不是很好。另外,在添加INDEX(a,b)时,删除INDEX(a)

A (as b):INDEX(col2,col4) --这个顺序a: INDEX( col4,col3,someColumn) -col4 first

票数 2
EN

Stack Overflow用户

发布于 2022-01-01 08:35:53

如果您的t.col_black_elem是由另一个查询获得的,则可以尝试使用左联接检查不匹配值。

代码语言:javascript
复制
   SELECT a.col1,..., a.coln
   from table1 a 
   LEFT JOIN (
        select col_black_elem from tablex 
   ) t on t.col_black_elem = a.colx 
   WHERE  t.col_black_elem  is null

还有你的密码

代码语言:javascript
复制
SELECT * 
FROM
    (
        (
        SELECT DISTINCT a.col1, a.col2, a.col3, a.col4,..., a.coln
        FROM
            `a`
            INNER JOIN ( SELECT MAX( b.col4 ) AS X, b.col2 FROM `a` AS `b` GROUP BY b.col2 ORDER BY NULL ) sub ON ( sub.X = a.col4 ) 
        WHERE
            ( a.someColumn > NOW( ) - INTERVAL 2 HOUR ) 
            AND ( a.col3 < DATE_HERE ) 
        ) UNION
        (
        SELECT  a.col1, a.col2, a.col3, a.col4,..., a.coln
        FROM
            `a` 
        WHERE
            ( a.someColumn >= DATE_SUB( NOW( ), INTERVAL 3 MONTH ) AND a.col4 IS NULL ) 
            AND ( a.col3 < DATE_HERE ) 
        ) 
    ) AS resultSet 
LEFT JOIN (
        select col_black_elem from tablex 
   ) t on t.col_black_elem =  resultSet.col1
WHERE  t.col_black_elem  is null
ORDER BY
    resultSet.col3 ASC,
    resultSet.col2 ASC,
    resultSet.col4 ASC,
    resultSet.col1 DESC

否则,如果您的t.col_black_elem不是通过另一个查询获得的,您可以使用几个选择的联合来打开一个临时表或一个粗大的临时表。

票数 1
EN

Stack Overflow用户

发布于 2022-01-01 11:09:40

从表演的角度来看,我重新评论你:

  1. 在第一个子查询中删除不同的内容。一个排序比在子查询中的两个sortings.
  2. Filter行更好,而不是在合并行集中,这将减少由UNION.

排序的行数。

代码语言:javascript
复制
SELECT * 
FROM
    (
        (
        SELECT a.col1, a.col2, a.col3, a.col4,..., a.coln
        FROM
            `a`
            INNER JOIN ( SELECT MAX( b.col4 ) AS X, b.col2 FROM `a` AS `b` GROUP BY b.col2 ORDER BY NULL ) sub ON ( sub.X = a.col4 ) 
        WHERE
            ( a.someColumn > NOW( ) - INTERVAL 2 HOUR ) 
            AND ( a.col3 < DATE_HERE ) 
            AND a.col1 NOT IN ( 1,10,20,30,40,50,60,70,80,90,100 ) 

        ) UNION
        (
        SELECT  a.col1, a.col2, a.col3, a.col4,..., a.coln
        FROM
            `a` 
        WHERE
            ( a.someColumn >= DATE_SUB( NOW( ), INTERVAL 3 MONTH ) AND a.col4 IS NULL ) 
            AND ( a.col3 < DATE_HERE ) 
            AND a.col1 NOT IN ( 1,10,20,30,40,50,60,70,80,90,100 ) 

        ) 
    ) AS resultSet 
ORDER BY
    resultSet.col3 ASC,
    resultSet.col2 ASC,
    resultSet.col4 ASC,
    resultSet.col1 DESC
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70547696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档