会员资格,会员和付款表中的10,000个数据。在每个成员的最新付款中搜索特定付款状态时,检索查询的速度太慢。
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
EXPLAIN
查询运行速度太慢21.00秒到99.00秒
答案 0 :(得分:2)
<小时/>的 ISSUE 强>
在mysql查询中页面正在减速(3-5分钟而不是秒),这些查询具有多个连接和子查询以检索表中的大量数据(~10,000)。
添加了索引并完成了各种搜索查询,它正在检索更好。
<小时/> 备注强>
索引用于快速查找具有特定列值的行。如果没有索引,MySQL必须从第一行开始,然后读取整个表以查找相关行。表越大,成本越高。如果表中有相关列的索引,MySQL可以快速确定要在数据文件中间寻找的位置,而无需查看所有数据。这比按顺序读取每一行要快得多。
提高SELECT操作性能的最佳方法是在查询中测试的一个或多个列上创建索引。索引条目的作用类似于表行的指针,允许查询快速确定哪些行与WHERE子句中的条件匹配,并检索这些行的其他列值。可以索引所有MySQL数据类型。
eg: ALTER TABLE `memberships` ADD INDEX ( `category_id` ) ;
DrawBack :索引是您可以在MySQL表上启用的额外功能,以提高性能,但它们确实有一些缺点。当您创建新索引时,MySQL会构建一个单独的信息块,每次对表进行更改时都需要更新这些信息块。这意味着如果您不断更新,插入和删除表格中的条目,则可能会对性能产生负面影响。
教程mysql.com,howtoforge.com,tizag.com
<小时/> <强>感谢强>
@venca @Boris @Raja Amer Khan和所有
感谢所有人帮我解决问题。
答案 1 :(得分:1)
首先确保为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