我有一个包含400多个事件的'事件'表,其中包含以下关系 - 一对多有event_dates(45,000行),一对多有event_categories(1,000行)。
我会很感激所有建议,重新改进这个冗长而缓慢的查询(我的sql技能很差):
SELECT
events.id AS id,
events.name AS event,
events.listing_type AS TYPE ,
GROUP_CONCAT( DISTINCT event_categories.category_id ) AS category_id,
events.location AS location,
events.summary AS summary,
counties.name AS county,
events.postcode AS postcode,
events.picture AS picture,
events.venue AS venue,
events.lat AS lat,
events.lng AS lng
FROM
EVENTS ,
event_dates,
event_categories,
counties,
categories
WHERE
events.preview =0
AND event_dates.start_date > DATE( NOW( ) )
AND events.id = event_dates.event_id
AND events.id = event_categories.event_id
AND events.county_id = counties.id
AND event_categories.category_id = categories.id
AND events.city LIKE '%London%'
GROUP BY id
ORDER BY events.id DESC
编辑: 这是个 事件搜索查询,它需要按类别表和日期表进行搜索。表结构如下:
event_dates:id start_date end_date start_time end_time event_id
event_categories:id event_id category_id
答案 0 :(得分:3)
我将您的查询重写为:
SELECT e.id,
e.name AS event,
e.listing_type AS TYPE ,
ec.category_id,
e.location,
e.summary,
co.name AS county,
e.postcode,
e.picture,
e.venue,
e.lat,
e.lng
FROM EVENTS e
JOIN EVENT_DATES ed ON ed.event_id = e.id
JOIN (SELECT t.event_id,
GROUP_CONCAT( DISTINCT t.category_id ) AS category_id
FROM EVENT_CATEGORIES t
GROUP BY t.event_id) ec ON ec.event_id = e.id
JOIN COUNTIES co ON c.id = e.county_id
WHERE e.preview = 0
AND ed.start_date > DATE( NOW( ) )
AND e.city LIKE '%London%'
ORDER BY e.id DESC
EVENTS.city
上有一个通配符,则左侧使用通配符LIKE搜索将无法使用索引(IE:'%London%')答案 1 :(得分:2)
我认为你应该在更小的范围内进行GROUP_CONCAT操作(作为FROM子句中的子查询),这可能会提高整体性能。因此,也会从查询中删除表categories
,因为它除了混淆之外没有任何贡献(除非您的表处于语义不完整状态,以至于您在event_categories中没有出现类别ID值定义类别表)。
这些观察结果导致:
SELECT e.id AS id,
e.name AS event,
e.listing_type AS type,
cat.category_id AS category_id,
e.location AS location,
e.summary AS summary,
counties.name AS county,
e.postcode AS postcode,
e.picture AS picture,
e.venue AS venue,
e.lat AS lat,
e.lng AS lng
FROM Events AS e
JOIN event_dates AS d ON e.id = d.id AND d.start_date > DATE(NOW())
JOIN (SELECT id, GROUP_CONCAT(category_id) AS category_id
FROM event_categories
GROUP BY id
) AS cat ON e.id = cat.id
JOIN counties ON e.county_id = counties.id
WHERE e.preview = 0
AND e.city LIKE '%London%'
ORDER BY events.id DESC
如果您确实需要查询中的类别表,那么它属于子查询:
SELECT e.id AS id,
e.name AS event,
e.listing_type AS type,
cat.category_id AS category_id,
e.location AS location,
e.summary AS summary,
counties.name AS county,
e.postcode AS postcode,
e.picture AS picture,
e.venue AS venue,
e.lat AS lat,
e.lng AS lng
FROM Events AS e
JOIN event_dates AS d ON e.id = d.id AND d.start_date > DATE(NOW())
JOIN (SELECT id, GROUP_CONCAT(category_id) AS category_id
FROM event_categories AS ec
JOIN categories AS ct ON ec.category_id = ct.category_id
GROUP BY id
) AS cat ON e.id = cat.id
JOIN counties ON e.county_id = counties.id
WHERE e.preview = 0
AND e.city LIKE '%London%'
ORDER BY events.id DESC
答案 2 :(得分:0)
首先,摆脱AND events.city LIKE '%London%'
并使您的位置定位依赖于county_id(我希望是外键)