嗨我在我的应用程序中对角度js进行了分页,我将数据发送到包含用户设置的过滤器的大查询
UPDATE SQL_CALC_FOUND_ROWS这是我的问题。如何计算特定过滤器的行数。 10万行需要2秒钟我需要分页编号作为总数
更新: 我在这里错过了以下内部查询:
(从学生中选择count(*)作为inner_st,其中st.name = inner_st.name)作为名称,
当我删除上面的内部查询要快得多
行:50,000 用户表:4行 类表:4行 索引:只将id作为主键
查询时间20-40秒
tables: students.
columns : id, date ,class, name,image,status,user_id,active
table user
coloumn: id,full_name,is_admin
查询
SELECT SQL_CALC_FOUND_ROWS st.id,
st.date,
st.image,
st.user_id,
st.status,
st,
ck.name AS class_name,
users.full_name,
(select count(*) from students AS inner_st where st.name = inner_st.name) AS names,
FROM students AS st
LEFT JOIN users ON st.user_id = users.user_id
LEFT JOIN classes AS ck ON st.class = ck.id
WHERE date BETWEEN '2018-01-17' AND DATE_ADD('2018-01-17', INTERVAL 1 DAY)
AND DATE_FORMAT(date,'%H:%i') >= '00:00'
AND DATE_FORMAT(date,'%H:%i') <= '23:59'
AND st.active=1
-- here I can concat filters from web like "and class= 1"
ORDER BY st.date DESC
LIMIT 0, 10
如何让它更快?当我删除订单和SQL_CALC_FOUND_ROWS它更快但我需要它们 我听说过索引,但只有主键是索引
答案 0 :(得分:1)
在推荐针对此查询的不同方法之前,很少有评论:
SQL_CALC_FOUND_ROWS
而是运行两个查询(一个计数,一个选择数据)?在某些情况下,它可能比将它们连接到一个查询更快。AND DATE_FORMAT(st.date, '%H:%i') >= '00:00' AND DATE_FORMAT(st.date, '%H:%i') <= '23:59'
要优化查询,我们首先添加这些索引:
ALTER TABLE `classes` ADD INDEX `classes_index_1` (`id`, `name`);
ALTER TABLE `students` ADD INDEX `students_index_1` (`active`, `user_id`, `class`, `name`, `date`);
ALTER TABLE `users` ADD INDEX `users_index_1` (`user_id`, `full_name`);
现在创建临时表(最初这是SELECT子句中的子查询)并将其编入索引:
-- Transformed subquery to a temp table to improve performance
CREATE TEMPORARY TABLE IF NOT EXISTS temp1 AS SELECT
count(*) AS names,
name
FROM
students AS inner_st
WHERE
1 = 1
GROUP BY
name
ORDER BY
NULL
-- This index is required for optimal temp tables performance
ALTER TABLE
`temp1`
ADD
INDEX `temp1_index_1` (`name`, `names`);
修改后的查询:
SELECT
SQL_CALC_FOUND_ROWS st.id,
st.date,
st.image,
st.user_id,
st.status,
ck.name AS class_name,
users.full_name,
temp1.names
FROM
students AS st
LEFT JOIN
users
ON st.user_id = users.user_id
LEFT JOIN
classes AS ck
ON st.class = ck.id
LEFT JOIN
temp1
ON st.name = temp1.name
WHERE
st.date BETWEEN '2018-01-17' AND DATE_ADD('2018-01-17', INTERVAL 1 DAY)
AND st.active = 1
ORDER BY
st.date DESC LIMIT 0,
10
答案 1 :(得分:0)
先尝试一下:
INDEX(active, date)
user_id
是users
的PK吗? class_id
是classes
的PK吗?如果没有,那么它们应该是INDEXed
。
为什么要分开测试时间?
修复测试,以便明确每列所在的表格。
你真的需要LEFT JOIN
吗?或者JOIN
会满足吗?在后一种情况下,还有更多优化选项。
提供其他SELECTs
的一些实际例子;可能需要不同的索引。
“第一”页面是否缓慢?还是只有以后的页面?有关分页优化的信息,请参阅this - not 使用OFFSET
。