【问题标题】:How in SQL search and get count for huge table (where-in)如何在 SQL 中搜索并获取大表的计数(在哪里)
【发布时间】:2013-12-22 14:28:18
【问题描述】:

我有sql表:

id  user    city
1   Alisa   New York
2   Alisa   Sydney
3   Alisa   Rom
4   Alisa   Toronto
5   Bob     Rom
6   Bob     Moskow
7   Bob     Sydney
8   Tom     Sydney

例如,我需要知道有多少相同的城市有 Bob 的其他用户。

SELECT user, count(DISTINCT city) FROM table WHERE city IN (
   SELECT city FROM table WHERE user = 'Bob'
) AND user != 'Bob' GROUP BY user

结果是:

user    count(DISTINCT city)
Alisa   2
Tom     1

您知道提出此请求的其他最佳方式吗? 大桌子可以吗?

【问题讨论】:

  • 我有 8205091 行,这个 sql 请求耗时:1 分 59.27 秒

标签: mysql sql group-by where-in


【解决方案1】:

这个怎么样:

SELECT A.user, 
       count(DISTINCT A.city)
FROM table  A,
     (SELECT city FROM table WHERE user = 'Bob') B
WHERE A.city = B.city
AND A.user != 'Bob'
GROUP BY A.user

【讨论】:

  • 此解决方案与@Christos Paisios 解决方案相同,因为临时 B 视图运行一次。
  • 24.55 秒更快 :)
  • 很高兴听到这更快。
【解决方案2】:

您应该输入一些数据,然后执行EXPLAIN

如果“OK”,这是以合理准确度进行预测的唯一方法。

【讨论】:

    【解决方案3】:
    CREATE TEMPORARY TABLE Cities (city varchar(100)); 
    INSERT INTO Cities SELECT city FROM table WHERE user = 'Bob';
    
    SELECT user, count(DISTINCT t.city) 
    FROM table AS t
    INNER JOIN Cities AS c ON t.City=c.City
    AND t.user !='Bob'
    GROUP BY User
    

    您可以创建一个临时表,在其中存储 Bob 所在的城市,然后在您的表和您创建的临时表之间进行内部连接。

    【讨论】:

    • 44.76 秒,这不是最好的方法 :(
    【解决方案4】:

    您可以使用自联接或EXISTS 来执行此操作,这两者都比尝试使用IN (SELECT ...) 好得多,这绝不是一个好主意。这是否“适合大表”取决于您对“好的”和“大表”的定义以及您的架构,但这至少应该有助于为您指明正确的方向。

    这是EXISTS 版本:

    SELECT user, count(DISTINCT city) 
    FROM table as main_query
    WHERE user != 'Bob' 
    AND EXISTS (
      SELECT NULL 
      FROM table as sub_query 
      WHERE sub_query.user = 'Bob' 
      and sub_query.city = main_query.city
    )
    GROUP BY user
    

    【讨论】:

    • 表上有索引吗?如果没有,请尝试在城市和用户上创建索引。
    猜你喜欢
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 2013-02-09
    • 2015-11-03
    • 1970-01-01
    • 2014-09-15
    • 2018-06-16
    • 2018-09-15
    相关资源
    最近更新 更多