我正在编写一个大型查询,它必须从许多表中查询数据。 (11桌)
我正在重写一个脚本,它有很大的性能问题。 该脚本可以生成数千个(有时是数万个)小查询,而不是几个大查询。查询可能需要数小时才能完成,并且可能会占用大量内存。 它目前的工作方式是这样的。 1)查询db的匹配事件 2)即返回500行。 3)循环遍历行,并从每个关联的表中获取其他数据
foreach(rows as row) {
row.user = /* query db for user data */
row.products = /* query db for product data */
row.productMeta = /* query db for additional data */
... and so on, for 11 tables
}
因此,500行将创建500 x 11个查询。
我的目标是以某种方式重写脚本 在1-2个大型查询中加入和评估MySql服务器端的所有条件。
这是一个问题。 制作此大型查询的最有效方法是什么? 如果我评估条件,它会有所作为吗? 加入ON子句,与外部WHERE子句相比。
i.e
SELECT * FROM events
INNER JOIN users ON users.event_id = events.id AND <condition 1>
INNER JOIN products ON products.event_id = events.id AND <condition 2>
LEFT JOIN inventory ON inventory.event_id = events.id AND <condition 3>
VS
SELECT * FROM events
INNER JOIN users ON users.event_id = events.id
INNER JOIN products ON products.event_id = events.id
LEFT JOIN inventory ON inventory.event_id = events.id
WHERE
<condition 1>
AND <condition 2>
AND <condition 3>
VS
making a few more queries to pre-filter the events, then join
$userIds = "make separate join to return event ids where users.event_id = events.id AND <condition 1>"
$productIds = "make separate join to return event ids where products.event_id = events.id AND <condition 2>"
Then:
SELECT * FROM events
INNER JOIN users ON users.event_id = events.id
INNER JOIN products ON products.event_id = events.id
LEFT JOIN inventory ON inventory.event_id = events.id
WHERE
events.id IN ($userIds) OR events.id IN ($productIds)
PS:所有相关列都已编入索引
答案 0 :(得分:0)
是的,你是正确的避免500 * 11查询。
对于JOIN
,您放入ON
还是WHERE
并不重要。 然而它是&#34;正确的&#34;把它放在WHERE
。
对于LEFT JOIN
,确实很重要。因此,坚持ON
仅表示表格如何相关的原则,以及WHERE
过滤器。
IN ( list )
有时会影响优化程序选择最佳索引的能力。所以,暂时不使用这种方法。
OR
几乎总是不好表现。尽可能避免使用它。一种解决方法是使用UNION
。
如果您没有提及GROUP BY
,可能会出现其他一些问题。
底线:选项2 似乎是最好的。
无论最终查询是什么样的,您可能都需要重新访问表上的索引。请参阅my cookbook。
你只是轻率地挥舞着这个问题,所以我只能给出一个挥手的建议。也许您想更接近拼写选项2方法。并加入SHOW CREATE TABLE
。