如何在 pandas 中提高 mysql 查询的处理速度

How to increase the processing speed of mysql query in pandas

我在元组中的ID如下

ids = tuple(df1['ids'])

ID 有 10 万行

我的查询

q_id=f'''

SELECT id, COUNT(*) AS Count 
FROM NEWS 
WHERE status = 'JOINED' AND id IN {ids} 
GROUP BY 1

connection是通过用户名和密码建立连接的方法

df2 = connection('mysqldb', q_id)

得到结果花了太多时间。如何在pandas中提高mysql查询的处理速度?

请提供SHOW CREATE TABLE news.

需要包含

 INDEX(status, id)

idPRIMARY KEY 吗?如果是这样,那么这是一个相当奇怪的查询:

SELECT id, COUNT(*) AS Count 
    FROM NEWS 
    WHERE status = 'JOINED'
      AND id IN {ids} 
    GROUP BY 1

因为所有计数都将为“1”。 (这是因为 PRIMARY KEY 是 "unique")。

找出这些 ID 中有多少 'JOINED':

SELECT COUNT(*) AS Count 
    FROM NEWS 
    WHERE status = 'JOINED'
      AND id IN {ids} 

找出哪个的id是'JOINED':

SELECT id 
    FROM NEWS 
    WHERE status = 'JOINED'
      AND id IN {ids} 

如果你有 id 作为 table 那么你可以使用 where exists (select 1 from ids where ids.key = NEWS.Key)

为了速度,组合查询几乎总是更有效。

您的问题暗示涉及三个步骤(3 个单独的 SQL 查询):

  1. 获取 ID 列表,
  2. 检查 ID(显示的查询查找哪些 ID 是 'joined'),
  3. 以某种方式使用这些 ID。

更好的办法是将查询组合在一起。一种简单的方法是让对 id 的搜索成为一个 'derived' table,它为进程的其余部分提供 id。通常最好将查询进一步混合在一起。

(如果我们知道其余的处理过程,我们或许可以提供具体的建议。)

您的查询为每个 ID 生成 01。如果你得到 NULLid 怎么办?还是找到"joined"的ids然后把剩下的扔掉?这样做可以加快您的查询速度。但是,它提供的是连接的 ID,而不是 0 或 1:

SELECT id FROM NEWS WHERE status = 'JOINED' AND id IN(...);

这将有助于提高效率:

INDEX(status, id)

在下面的两个示例中,我着重于合并第二个和第三个查询。

SELECT ...
    FROM ...
    LEFT JOIN ( SELECT id FROM NEWS WHERE status = 'JOINED' ) x
            USING(id);

有了它,您可以使用 id 或得到一个 NULL 表明它不是 "joined"。

那也可以这样写

SELECT ...
    FROM mytable AS a
    WHERE EXISTS ( SELECT 1 FROM NEWS
            WHERE status = 'JOINED'
              AND id = a.id )

这确实产生 01,被视为 falsetrue

不清楚是 LEFT JOIN 还是 EXISTS 更好。我们需要查看 id 列表的来源和您的 COUNTs 的使用。注意:在任何一种情况下,3 个查询中的第 2 个查询是有效组合的,很可能更快。

一些第 3 方包倾向于将 SQL 任务分解成像这样的小步骤(获取 ID、检查它们、使用它们)。这使得包更简单,但对于 "big".

的数据集来说效率低下