[英]Is it faster to run an SQL count(*) query in a loop, or try to merge it into the parent query?
我有一個SQL查詢。
SELECT `shifts`.*, `races`.`race_attrition_rate`
FROM `shifts`
JOIN `races` ON `races`.`race_id` = `shifts`.`race_id`
WHERE `shifts`.`race_id` = 'X'
AND `shift_deleted` =0
ORDER BY `shift_name` ASC, `shift_id` ASC
該查詢從數據庫中提取了志願者輪班列表。 然后,我有一個PHP循環,對於上述查詢中拉出的每個班次,都將運行此SQL查詢。
SELECT COUNT(*) AS `numrows`
FROM `volunteer_shifts`
WHERE `shift_id` = 'Y'
AND `shift_deleted` =0
因此,如果在第一個查詢中提取了5個班次,則第二個查詢將運行5次,每次查詢一次。
1)這兩個查詢可以合並在一起嗎? 合並后的代碼是什么樣的?
2)將這兩個查詢合並在一起的速度更快嗎?
3)將它們合並在一起可能會使代碼的可讀性降低。 那么什么是最佳實踐? 兩個可讀查詢還是一個難以理解但快速的查詢?
除非您發布表架構,否則我們不知道哪個會運行得更快。 如果您是我,我可能會運行查詢1,收集所有shift_id
然后再運行1個查詢,使用IN
來shift_id
列表的計數。
這樣的事情。
SELECT COUNT(*) AS `numrows`, `shift_id`
FROM `volunteer_shifts`
WHERE `shift_id` IN ('42','other number', 'more numbers'...)
AND `shift_deleted` =0
GROUP BY `shift_id`
在這種情況下,純SQL比在應用程序層(即PHP)循環更易於維護,可讀性和效率更高。 因此,考慮將聚合查詢作為派生表加入(注意shift_id現在是一個分組)。 現在,該計數將在一個查詢中與其他字段內聯顯示:
SELECT s.*, r.`race_attrition_rate`, agg.`numrows`
FROM `shifts` s
JOIN `races` r ON r.`race_id` = s.`race_id`
JOIN (
SELECT `shift_id`, COUNT(*) AS `numrows`
FROM `volunteer_shifts`
WHERE `shift_deleted` = 0
GROUP BY `shift_id`
) AS agg
ON agg.shift_id = s.shift_id
WHERE r.`race_id` = '17'
AND s.`shift_deleted` = 0
ORDER BY s.`shift_name` ASC, s.`shift_id` ASC
2)將這兩個查詢合並在一起的速度更快嗎?
單個查詢的速度將大大提高,因為無需花費任何時間進行網絡活動(假設數據庫位於另一台服務器上,這是很常見的情況)
另外,單獨查詢方法不允許內置的數據庫查詢優化器執行其工作
1)這兩個查詢可以合並在一起嗎? 合並后的代碼是什么樣的?
以下查詢可能適合您:
SELECT
`shifts`.*,
`races`.`race_attrition_rate`,
(SELECT
COUNT(*) AS `numrows`
FROM
`volunteer_shifts`
WHERE
`volunteer_shifts`.`shift_id` = `shifts`.`shift_id`
AND
`shift_deleted` = 0) AS `volunteer_shifts`
FROM
`shifts`
JOIN `races` ON `races`.`race_id` = `shifts`.`race_id`
WHERE
`shifts`.`race_id` = 'X'
AND
`shift_deleted` = 0
ORDER BY
`shift_name` ASC, `shift_id` ASC
3)那么什么是最佳實踐? 兩個可讀查詢還是一個難以理解但快速的查詢?
一般規則是“在性能出現問題之前,可讀性才是重點”。 僅僅因為計算資源比人力資源便宜
如果您想要的只是第二條SQL產生的計數,那么它將更具可讀性,並且會更短。
SELECT COUNT(*) numrows
FROM shifts
Where shift_id = 42
and race_id = '17'
and shift_deleted = 0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.