0
SELECT COUNT(organization.ID)
FROM organization
WHERE organization.NAME IN (
    SELECT organization.NAME
    FROM organization
    WHERE organization.NAME <> ''
        AND organization.APPROVED = 0 
        AND organization.CREATED_AT > '2012-07-31 04:31:08'
    GROUP BY organization.NAME
    HAVING COUNT(organization.ID) > 1
)

此查询查找重复项,问题是页面加载需要 6 秒,因为内部语句。有没有办法让它跑得更快?MySQL 数据库版本 5.1。

4

4 回答 4

1

是的。这很慢,因为 MySQL 在处理“in”查询方面很慢。您可以改用它来修复它:

SELECT COUNT(organization.ID)
FROM organization o
WHERE exists (
    SELECT organization.NAME
    FROM organization o2
    WHERE organization.NAME <> ''
        AND organization.APPROVED = 0 
        AND organization.CREATED_AT > '2012-07-31 04:31:08' and
        organization.name = o.organization.name
    GROUP BY organization.NAME
    HAVING COUNT(organization.ID) > 1
)
于 2012-08-31T20:53:38.167 回答
0

如果您要返回的是所有重复项的总“计数”,但仅适用于在 APPROVED 和 CREATED_AT 上具有指定谓词的两行或多行的组织名称,那么您可以使用备用语句返回等价的结果:

SELECT SUM(c.cnt) 
  FROM ( SELECT COUNT(organization.ID) AS cnt
           FROM organization o
          WHERE o.NAME <> ''
          GROUP
             BY o.NAME
         HAVING SUM(o.APPROVED = 0 AND o.CREATED_AT > '2012-07-31 04:31:08') > 1
       ) c

MySQL 可以利用一个合适的覆盖索引来满足这个查询,否则,这很可能是对组织表的全扫描。但它避免了两次引用组织表,并避免了 JOIN 操作。

此查询的一个合适的覆盖索引是:

ON organization (NAME, CREATED_AT, APPROVED, ID)

请注意,如果该ID列保证为非 NULL(NOT NULL 约束或其表的 PRIMARY KEY,则可以避免引用该列,并且可以将该列排除在索引定义之外。)

SELECT SUM(c.cnt) 
  FROM ( SELECT SUM(1) AS cnt
           FROM organization o
          WHERE o.NAME <> ''
          GROUP
             BY o.NAME
         HAVING SUM(o.APPROVED = 0 AND o.CREATED_AT > '2012-07-31 04:31:08') > 1
       ) c

EXPLAIN 输出显示此查询使用索引来满足查询,而不引用表中的任何数据块:

id  select_type  table       type    possible_keys    key              key_len  ref       rows  Extra                     
--  -----------  ----------  ------  ---------------  ---------------  -------  ------  ------  --------------------------
 1  PRIMARY      <derived2>  ALL     (NULL)           (NULL)           (NULL)   (NULL)       2                            
 2  DERIVED      o           index   organization_ix  organization_ix  44       (NULL)      29  Using where; Using index  
于 2012-08-31T21:23:58.507 回答
0

我还发现为包含的 db 字段创建索引极大地提高了复杂查询的速度。

于 2012-08-31T20:58:01.143 回答
0

尽量避免IN

SELECT COUNT(organization.ID)
FROM 
    organization
    INNER JOIN 
    (
        SELECT organization.NAME
        FROM organization
        WHERE organization.NAME <> ''
            AND organization.APPROVED = 0 
            AND organization.CREATED_AT > '2012-07-31 04:31:08'
        GROUP BY organization.NAME
        HAVING COUNT(organization.ID) > 1
    ) AS t ON organization.NAME = t.Name
于 2012-08-31T20:52:29.213 回答