mysql优化
我有一个包含400多个事件的“事件”表,其中包含以下关系:一对多的事件(45000行),一对多的事件(1000行) 如果有人建议重新改进这个冗长而缓慢的查询(我的sql技能相当差),我将不胜感激: 编辑: 这是一个 事件搜索查询,需要同时按类别表和日期表进行搜索。下表结构: 事件日期:mysql优化,mysql,optimization,Mysql,Optimization,我有一个包含400多个事件的“事件”表,其中包含以下关系:一对多的事件(45000行),一对多的事件(1000行) 如果有人建议重新改进这个冗长而缓慢的查询(我的sql技能相当差),我将不胜感激: 编辑: 这是一个 事件搜索查询,需要同时按类别表和日期表进行搜索。下表结构: 事件日期:id开始日期结束日期开始时间结束时间事件id 事件类别:id event\u id category\u id一方面,摆脱像“%London%”这样的和events.city,让你的位置定位依赖于县id(我希望是外
id开始日期结束日期开始时间结束时间事件id
事件类别:
id event\u id category\u id
一方面,摆脱像“%London%”这样的和events.city
,让你的位置定位依赖于县id(我希望是外键),摆脱像“%London%”这样的和events.city
,使您的定位目标依赖于县id(我希望是外键)我将您的查询重新编写为:
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
你有:
- 连接到CATEGORIES表,但未使用它
- 虽然OP中的GROUP BY在MySQL上有效,但此版本是SQL标准
- 如果
(即:'%London%')上有索引,则通过左侧带有通配符的LIKE搜索将无法使用索引EVENTS.city
- 为连接条件列编制索引(如果尚未编制),然后查看WHERE子句中的列的索引
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
你有:
- 连接到CATEGORIES表,但未使用它
- 虽然OP中的GROUP BY在MySQL上有效,但此版本是SQL标准
- 如果
(即:'%London%')上有索引,则通过左侧带有通配符的LIKE搜索将无法使用索引EVENTS.city
- 为连接条件列编制索引(如果尚未编制),然后查看WHERE子句中的列的索引
categories
,因为它只会造成混乱(除非您的表处于语义不一致的状态,以至于您的事件\ u类别中的类别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
如果查询中确实需要categories表,则它属于子查询:
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
我认为您应该在更小的范围内(作为FROM子句中的子查询)执行GROUP_CONCAT操作,这可能会提高整体性能。因此,也将从查询中删除表
categories
,因为它只会造成混乱(除非您的表处于语义不一致的状态,以至于您的事件\ u类别中的类别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
如果查询中确实需要categories表,则它属于子查询:
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
post explain plan、show INDEX from和describe plus简要说明您正在尝试完成的工作-谢谢:)使用显式连接表示法连接表。我支持f00-我怀疑连接的排序可能效率低下,至少是这样。此外,正如coolgeek指出的,“LIKE”(和其他字符串比较)往往相对较慢,并且会影响性能。第三个考虑因素是组中的DISTINCT-如果事件类别是一个真正的多对多表,那么单个事件条目不应该有重复的类别条目,并且在该表上使用多值PK将允许您在此查询中删除DISTINCT。post explain plan,show index from和descripe plus简要描述您正在尝试完成的任务-谢谢:)使用显式连接表示法连接表。我支持f00-我怀疑连接的排序可能效率低下,至少是这样。此外,正如coolgeek指出的,“LIKE”(和其他字符串比较)往往相对较慢,并且会影响性能。第三个考虑因素是组中的DISTINCT-如果事件类别是一个真正的多对多表,那么单个事件条目不应该有重复的类别条目,并且在该表上使用多值PK将允许您在该查询中删除DISTINCT。+1:关于如何包括类别的说明。。。和我的格式非常相似。+1:关于如何包含类别的注释。。。格式和我的非常相似。谢谢你们。出于某种奇怪的原因,我的查询时间从6秒缩短到了58秒。但真正起作用的是,正如您所说的那样,对连接进行适当的索引(现在是0.05秒)。干杯,谢谢你们。出于某种奇怪的原因,我的查询时间从6秒缩短到了58秒。但真正起作用的是,正如您所说的那样,对连接进行适当的索引(现在是0.05秒)。干杯