我有 5 个 SQL 表
我创建了一个将这四个表连接在一起的视图。最后一个表 (staff_rating),我想在接近视图行的商品售出时间 (sold_items.date) 的时间获取评级列。 我尝试了以下 SQL 查询,这些查询有效但存在性能问题。
SQL 查询 1
SELECT s.name,
s.country,
d.name,
si.item,
si.date,
(SELECT rating
FROM staff_ratings
WHERE staff_id = s.id
ORDER BY DATEDIFF(date, si.date) LIMIT 1) AS rating,
st.name,
st.owner
FROM store st
LEFT OUTER JOIN staff s ON s.store_id = st.id
LFET JOIN departments d ON d.store_id = st.id
LEFT JOIN sold_items si ON si.store_id = st.id
SQL 查询 2
SELECT s.name,
s.country,
d.name,
si.item,
si.date,
si.rating ,
st.name,
st.owner
FROM store st
LEFT OUTER JOIN staff s ON s.store_id = st.id
LFET JOIN departments d ON d.store_id = st.id
LEFT JOIN (SELECT *,
(SELECT rating
FROM staff_ratings
WHERE staff_id = si.staff_id
ORDER BY DATEDIFF(date, si.date) LIMIT 1) AS rating
FROM sold_items) si ON si.store_id = st.id
SQL Query 2 比 SQL Query 1 快。但两者仍然存在性能问题。感谢对具有更好性能的查询的帮助。提前致谢。
答案 0 :(得分:0)
您的查询在我看来不正确(如对原始帖子的评论中所述;在销售联接中缺少员工 ID 等)
忽略这一点,你最大的表现之一可能是这个......
ORDER BY DATEDIFF(date, si.date) LIMIT 1
只能通过比较该员工的每条记录与当前销售记录来回答该订单。
理想情况下,您希望能够从索引中找到合适的员工评级,而不必运行涉及评级表和销售表中日期的计算。
例如,如果您想要“销售前的最新评级”,则可以显着改善查询...
SELECT
s.name,
s.country,
d.name,
si.item,
si.date,
(
SELECT sr.rating
FROM staff_ratings sr
WHERE sr.staff_id = s.id
AND sr.date <= si.date
ORDER BY sr.date DESC
LIMIT 1
)
AS rating,
st.name,
st.owner
FROM store st
LEFT JOIN staff s ON s.store_id = st.id
LFET JOIN departments d ON d.store_id = st.id
LEFT JOIN sold_items si ON si.store_id = st.id
然后,使用 staff_ratings(staff_id, date, rating)
的索引,优化器可以非常快速地查找要使用的评级,而无需扫描该员工的每个评级。
答案 1 :(得分:0)
为什么是DATEDIFF
?这样的事情会更好吗?如果是这样,给定的索引将使其工作得更快。
WHERE staff_id = s.id
AND s.date >= s1.date
ORDER BY s.date
LIMIT 1
还有INDEX(staff_id, date)
你需要LEFT JOIN
吗?也许简单的JOIN
?
d
可能受益于 INDEX(store_id, name)