mysql 查询从 10,000 条数据中检索太慢(查询优化)
mysql query retrieve too slow from 10,000 of data (Query Optimizing)
10,000 条会员、会员和付款方面的数据 table。检索查询太慢,同时在每个成员最新付款中搜索特定付款状态。
SELECT m.id AS member_id, m.full_name, m.unit, m.street, m.block, m.country, m.postal_code, cat . * , cat.id AS cat_id, mem.membership_num, mem.id AS membership_id
FROM memberships mem
LEFT JOIN category cat ON mem.category_id = cat.id
LEFT JOIN members m ON mem.member_id = m.id
WHERE m.id >0
AND m.status = 'active'
AND (
mem.category_id
BETWEEN 1
AND 11
)
AND (
SELECT p1.payment_status_id
FROM payments p1
WHERE p1.category_id = cat.id
AND p1.member_id = mem.member_id
AND p1.payment_status_id = '1'
LIMIT 1
) != ''
GROUP BY CONCAT( cat.id, '_', m.unit, '_', m.postal_code )
ORDER BY m.full_name ASC
LIMIT 0 , 25
解释
查询运行太慢 21.00 秒到 99.00 秒
首先确保您已经为JOINS 和WHERE 子句中涉及的所有列创建了索引。此外,如果您创建了复合索引,请确保它们的顺序与查询中的顺序相同。尝试以下操作,看看是否有任何不同:
SELECT m.id AS member_id,
m.full_name,
m.unit,
m.street,
m.block,
m.country,
m.postal_code,
cat . * ,
cat.id AS cat_id,
mem.membership_num,
mem.id AS membership_id
FROM memberships mem
LEFT JOIN members m ON m.id = mem.member_id
LEFT JOIN category cat ON cat.id = mem.category_id
INNER JOIN payments p1 ON p1.category_id = mem.category_id
AND p1.member_id = mem.member_id
AND p1.payment_status_id = '1'
WHERE m.id > 0
AND mem.category_id BETWEEN 1 AND 11
AND m.status = 'active'
GROUP BY CONCAT( cat.id, '_', m.unit, '_', m.postal_code )
ORDER BY m.full_name ASC
LIMIT 0 , 25
问题
mysql 查询中的页面速度变慢(3-5 分钟而不是几秒),这些查询具有多个连接和子查询以在 table 中检索大量数据(~10,000)秒。
解决方案 - 使用列索引
添加了索引并进行了各种搜索查询,检索效果更好。
注释
索引用于快速查找具有特定列值的行。如果没有索引,MySQL 必须从第一行开始,然后通读整个 table 以找到相关行。 table越大,成本越高。如果 table 有相关列的索引,MySQL 可以快速确定要在数据文件中间查找的位置,而无需查看所有数据。这比顺序读取每一行要快得多。
提高SELECT 操作性能的最佳方法是在查询中测试的一个或多个列上创建索引。索引条目就像指向 table 行的指针,允许查询快速确定哪些行与 WHERE 子句中的条件匹配,并检索这些行的其他列值。所有 MySQL 数据类型都可以被索引。
eg: ALTER TABLE `memberships` ADD INDEX ( `category_id` ) ;
缺点:索引是一些额外的东西,您可以在 MySQL table 上启用它来提高性能,但它们确实有一些缺点。当您创建新索引时,MySQL 会构建一个单独的信息块,每次对 table 进行更改时都需要更新该信息块。这意味着如果您不断更新、插入和删除 table 中的条目,这可能会对性能产生负面影响。
教程mysql.com, howtoforge.com, tizag.com
谢谢
@venca @Boris @Raja Amer Khan 和所有
感谢大家帮我解决问题。
10,000 条会员、会员和付款方面的数据 table。检索查询太慢,同时在每个成员最新付款中搜索特定付款状态。
SELECT m.id AS member_id, m.full_name, m.unit, m.street, m.block, m.country, m.postal_code, cat . * , cat.id AS cat_id, mem.membership_num, mem.id AS membership_id
FROM memberships mem
LEFT JOIN category cat ON mem.category_id = cat.id
LEFT JOIN members m ON mem.member_id = m.id
WHERE m.id >0
AND m.status = 'active'
AND (
mem.category_id
BETWEEN 1
AND 11
)
AND (
SELECT p1.payment_status_id
FROM payments p1
WHERE p1.category_id = cat.id
AND p1.member_id = mem.member_id
AND p1.payment_status_id = '1'
LIMIT 1
) != ''
GROUP BY CONCAT( cat.id, '_', m.unit, '_', m.postal_code )
ORDER BY m.full_name ASC
LIMIT 0 , 25
解释
查询运行太慢 21.00 秒到 99.00 秒
首先确保您已经为JOINS 和WHERE 子句中涉及的所有列创建了索引。此外,如果您创建了复合索引,请确保它们的顺序与查询中的顺序相同。尝试以下操作,看看是否有任何不同:
SELECT m.id AS member_id,
m.full_name,
m.unit,
m.street,
m.block,
m.country,
m.postal_code,
cat . * ,
cat.id AS cat_id,
mem.membership_num,
mem.id AS membership_id
FROM memberships mem
LEFT JOIN members m ON m.id = mem.member_id
LEFT JOIN category cat ON cat.id = mem.category_id
INNER JOIN payments p1 ON p1.category_id = mem.category_id
AND p1.member_id = mem.member_id
AND p1.payment_status_id = '1'
WHERE m.id > 0
AND mem.category_id BETWEEN 1 AND 11
AND m.status = 'active'
GROUP BY CONCAT( cat.id, '_', m.unit, '_', m.postal_code )
ORDER BY m.full_name ASC
LIMIT 0 , 25
问题
mysql 查询中的页面速度变慢(3-5 分钟而不是几秒),这些查询具有多个连接和子查询以在 table 中检索大量数据(~10,000)秒。
解决方案 - 使用列索引
添加了索引并进行了各种搜索查询,检索效果更好。
注释
索引用于快速查找具有特定列值的行。如果没有索引,MySQL 必须从第一行开始,然后通读整个 table 以找到相关行。 table越大,成本越高。如果 table 有相关列的索引,MySQL 可以快速确定要在数据文件中间查找的位置,而无需查看所有数据。这比顺序读取每一行要快得多。
提高SELECT 操作性能的最佳方法是在查询中测试的一个或多个列上创建索引。索引条目就像指向 table 行的指针,允许查询快速确定哪些行与 WHERE 子句中的条件匹配,并检索这些行的其他列值。所有 MySQL 数据类型都可以被索引。
eg: ALTER TABLE `memberships` ADD INDEX ( `category_id` ) ;
缺点:索引是一些额外的东西,您可以在 MySQL table 上启用它来提高性能,但它们确实有一些缺点。当您创建新索引时,MySQL 会构建一个单独的信息块,每次对 table 进行更改时都需要更新该信息块。这意味着如果您不断更新、插入和删除 table 中的条目,这可能会对性能产生负面影响。
教程mysql.com, howtoforge.com, tizag.com
谢谢
@venca @Boris @Raja Amer Khan 和所有
感谢大家帮我解决问题。