如何在 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)
id
是 PRIMARY 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 查询):
- 获取 ID 列表,
- 检查 ID(显示的查询查找哪些 ID 是 'joined'),
- 以某种方式使用这些 ID。
更好的办法是将查询组合在一起。一种简单的方法是让对 id 的搜索成为一个 'derived' table,它为进程的其余部分提供 id。通常最好将查询进一步混合在一起。
(如果我们知道其余的处理过程,我们或许可以提供具体的建议。)
您的查询为每个 ID 生成 0
或 1
。如果你得到 NULL
或 id
怎么办?还是找到"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 )
这确实产生 0
或 1
,被视为 false
或 true
。
不清楚是 LEFT JOIN 还是 EXISTS 更好。我们需要查看 id
列表的来源和您的 COUNTs
的使用。注意:在任何一种情况下,3 个查询中的第 2 个查询是有效组合的,很可能更快。
一些第 3 方包倾向于将 SQL 任务分解成像这样的小步骤(获取 ID、检查它们、使用它们)。这使得包更简单,但对于 "big".
的数据集来说效率低下
我在元组中的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)
id
是 PRIMARY 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 查询):
- 获取 ID 列表,
- 检查 ID(显示的查询查找哪些 ID 是 'joined'),
- 以某种方式使用这些 ID。
更好的办法是将查询组合在一起。一种简单的方法是让对 id 的搜索成为一个 'derived' table,它为进程的其余部分提供 id。通常最好将查询进一步混合在一起。
(如果我们知道其余的处理过程,我们或许可以提供具体的建议。)
您的查询为每个 ID 生成 0
或 1
。如果你得到 NULL
或 id
怎么办?还是找到"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 )
这确实产生 0
或 1
,被视为 false
或 true
。
不清楚是 LEFT JOIN 还是 EXISTS 更好。我们需要查看 id
列表的来源和您的 COUNTs
的使用。注意:在任何一种情况下,3 个查询中的第 2 个查询是有效组合的,很可能更快。
一些第 3 方包倾向于将 SQL 任务分解成像这样的小步骤(获取 ID、检查它们、使用它们)。这使得包更简单,但对于 "big".
的数据集来说效率低下