求优化下sql语句

acgl4 2018-01-27 07:16:57
array(2) {
[0] => string(6) "4.1184"
[1] => string(316) "select a.custid from g_customer_tb a join g_customer_tbdata b on a.custid = b.custid where (b.rq > '2016-01-29 00:00:00 ' and b.rq < '2018-01-27 23:59:59') and a.shopid in (5,7,18,29,47,77,78,86,87,88,196,197,198,199) and( a.size1 = 1 or a.size2 = 1 or a.size3 = 1 ) group by b.custid having count(b.id) = 1"
}
前面是运行时间,后面是sql语句,数据量大概是四十万,
...全文
978 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
cattpon 2018-01-29
  • 打赏
  • 举报
回复
引用 29 楼 xiaocongzhi 的回复:
IN条件与OR条件看看能不能改成别的,这两种条件一般挺耗时的
相差应该没多少?!
xiaocongzhi 2018-01-29
  • 打赏
  • 举报
回复
IN条件与OR条件看看能不能改成别的,这两种条件一般挺耗时的
acgl4 2018-01-28
  • 打赏
  • 举报
回复
引用 11 楼 yenange 的回复:
分页: https://www.cnblogs.com/pinganzi/p/6645318.html
临时表: https://www.cnblogs.com/agang-php/p/5114264.html


貌似用临时表速度没有什么提高
acgl4 2018-01-27
  • 打赏
  • 举报
回复
引用 23 楼 yenange 的回复:
[quote=引用 22 楼 acgl4 的回复:]
[quote=引用 21 楼 yenange 的回复:]
[quote=引用 19 楼 acgl4 的回复:]
[quote=引用 18 楼 yenange 的回复:]
[quote=引用 17 楼 acgl4 的回复:]
分页的话我要先求出记录总行数再查询吗,但是页数越大,后面查询的数据也越慢

1. 没人会看完你几十万行的数据;
2. 很少人翻看最后几千上万页的页码。
前几页能快速出结果就行了。[/quote]
可是项目需求是求出这些custid保存到另外一张表里[/quote]

你早说嘛, 显示出来和插入到另外一张表, 这根本就不是一回事。
你这些数据, 插入到另外一张表, 肯定比显示出来要快得多。你自己试一下就知道 了

[/quote]
是先查询出来 显示条数,再缓存数据,等到执行插入操作的时候再把数据插到另外一张表[/quote]
到底需不需要显示内容?
如果不需要显示内容, 只显示条数, 可以先插入到一个临时用的表(不是临时表), 显示条数非常容易的, 速度也比较快。

[/quote]

就像这样,不过在加入计划的时候需要用到之前查询缓存下来的custid数据,同计划ID一起插入到另外一张表

吉普赛的歌 2018-01-27
  • 打赏
  • 举报
回复
引用 22 楼 acgl4 的回复:
[quote=引用 21 楼 yenange 的回复:] [quote=引用 19 楼 acgl4 的回复:] [quote=引用 18 楼 yenange 的回复:] [quote=引用 17 楼 acgl4 的回复:] 分页的话我要先求出记录总行数再查询吗,但是页数越大,后面查询的数据也越慢
1. 没人会看完你几十万行的数据; 2. 很少人翻看最后几千上万页的页码。 前几页能快速出结果就行了。[/quote] 可是项目需求是求出这些custid保存到另外一张表里[/quote] 你早说嘛, 显示出来和插入到另外一张表, 这根本就不是一回事。 你这些数据, 插入到另外一张表, 肯定比显示出来要快得多。你自己试一下就知道 了 [/quote] 是先查询出来 显示条数,再缓存数据,等到执行插入操作的时候再把数据插到另外一张表[/quote] 到底需不需要显示内容? 如果不需要显示内容, 只显示条数, 可以先插入到一个临时用的表(不是临时表), 显示条数非常容易的, 速度也比较快。
acgl4 2018-01-27
  • 打赏
  • 举报
回复
引用 21 楼 yenange 的回复:
[quote=引用 19 楼 acgl4 的回复:] [quote=引用 18 楼 yenange 的回复:] [quote=引用 17 楼 acgl4 的回复:] 分页的话我要先求出记录总行数再查询吗,但是页数越大,后面查询的数据也越慢
1. 没人会看完你几十万行的数据; 2. 很少人翻看最后几千上万页的页码。 前几页能快速出结果就行了。[/quote] 可是项目需求是求出这些custid保存到另外一张表里[/quote] 你早说嘛, 显示出来和插入到另外一张表, 这根本就不是一回事。 你这些数据, 插入到另外一张表, 肯定比显示出来要快得多。你自己试一下就知道 了 [/quote] 是先查询出来 显示条数,再缓存数据,等到执行插入操作的时候再把数据插到另外一张表
吉普赛的歌 2018-01-27
  • 打赏
  • 举报
回复
引用 19 楼 acgl4 的回复:
[quote=引用 18 楼 yenange 的回复:] [quote=引用 17 楼 acgl4 的回复:] 分页的话我要先求出记录总行数再查询吗,但是页数越大,后面查询的数据也越慢
1. 没人会看完你几十万行的数据; 2. 很少人翻看最后几千上万页的页码。 前几页能快速出结果就行了。[/quote] 可是项目需求是求出这些custid保存到另外一张表里[/quote] 你早说嘛, 显示出来和插入到另外一张表, 这根本就不是一回事。 你这些数据, 插入到另外一张表, 肯定比显示出来要快得多。你自己试一下就知道 了
acgl4 2018-01-27
  • 打赏
  • 举报
回复
引用 18 楼 yenange 的回复:
[quote=引用 17 楼 acgl4 的回复:]
分页的话我要先求出记录总行数再查询吗,但是页数越大,后面查询的数据也越慢

1. 没人会看完你几十万行的数据;
2. 很少人翻看最后几千上万页的页码。
前几页能快速出结果就行了。[/quote]

运行几次时间变长了好多。
acgl4 2018-01-27
  • 打赏
  • 举报
回复
引用 18 楼 yenange 的回复:
[quote=引用 17 楼 acgl4 的回复:] 分页的话我要先求出记录总行数再查询吗,但是页数越大,后面查询的数据也越慢
1. 没人会看完你几十万行的数据; 2. 很少人翻看最后几千上万页的页码。 前几页能快速出结果就行了。[/quote] 可是项目需求是求出这些custid保存到另外一张表里
吉普赛的歌 2018-01-27
  • 打赏
  • 举报
回复
引用 17 楼 acgl4 的回复:
分页的话我要先求出记录总行数再查询吗,但是页数越大,后面查询的数据也越慢
1. 没人会看完你几十万行的数据; 2. 很少人翻看最后几千上万页的页码。 前几页能快速出结果就行了。
acgl4 2018-01-27
  • 打赏
  • 举报
回复
分页的话我要先求出记录总行数再查询吗,但是页数越大,后面查询的数据也越慢
吉普赛的歌 2018-01-27
  • 打赏
  • 举报
回复
有效果就好。 php 没有用过, 但应该是不直接支持多行语句的了。 你看看这个有没有用: http://blog.csdn.net/tashanhongye/article/details/48895803
acgl4 2018-01-27
  • 打赏
  • 举报
回复
引用 13 楼 yenange 的回复:
[quote=引用 12 楼 acgl4 的回复:] [quote=引用 11 楼 yenange 的回复:] 分页: https://www.cnblogs.com/pinganzi/p/6645318.html 临时表: https://www.cnblogs.com/agang-php/p/5114264.html
很奇怪的是直接在数据库运行能成功,放到系统就出现错误 [/quote] #8 中的SQL 直接在数据库运行需要 几 秒?[/quote] 好像只显示0-29行所以时间这么短
acgl4 2018-01-27
  • 打赏
  • 举报
回复
引用 13 楼 yenange 的回复:
[quote=引用 12 楼 acgl4 的回复:] [quote=引用 11 楼 yenange 的回复:] 分页: https://www.cnblogs.com/pinganzi/p/6645318.html 临时表: https://www.cnblogs.com/agang-php/p/5114264.html
很奇怪的是直接在数据库运行能成功,放到系统就出现错误 [/quote] #8 中的SQL 直接在数据库运行需要 几 秒?[/quote] 就上面这个
吉普赛的歌 2018-01-27
  • 打赏
  • 举报
回复
引用 12 楼 acgl4 的回复:
[quote=引用 11 楼 yenange 的回复:] 分页: https://www.cnblogs.com/pinganzi/p/6645318.html 临时表: https://www.cnblogs.com/agang-php/p/5114264.html
很奇怪的是直接在数据库运行能成功,放到系统就出现错误 [/quote] #8 中的SQL 直接在数据库运行需要 几 秒?
acgl4 2018-01-27
  • 打赏
  • 举报
回复
引用 11 楼 yenange 的回复:
分页: https://www.cnblogs.com/pinganzi/p/6645318.html
临时表: https://www.cnblogs.com/agang-php/p/5114264.html

很奇怪的是直接在数据库运行能成功,放到系统就出现错误

acgl4 2018-01-27
  • 打赏
  • 举报
回复
引用 8 楼 yenange 的回复:
[quote=引用 7 楼 acgl4 的回复:] [quote=引用 6 楼 yenange 的回复:] 你那个SQL, 最终的输出结果是多少行?
190219行[/quote] 这个输出的数据量这么大, 需要 4 秒钟不算多吧? 下面这种做法你看能不能快一点:
--1. 建立临时表
CREATE TEMPORARY TABLE tmp_table
SELECT a.custid
FROM   g_customer_tb a
WHERE  a.shopid IN (5, 7, 18, 29, 47, 77, 78, 86, 87, 88, 196, 197, 198, 199)
       AND (a.size1 = 1 OR a.size2 = 1 OR a.size3 = 1);
CREATE INDEX ix_tmp_table ON tmp_table(custid); 
--2. 连接查询
SELECT a.custid
FROM   tmp_table a JOIN g_customer_tbdata b ON  a.custid = b.custid
WHERE  b.rq > '2016-01-29  00:00:00 ' AND b.rq < '2018-01-27 23:59:59'
GROUP BY b.custid
HAVING COUNT(b.id) = 1;
--3. 删除临时表;
DROP TABLE tmp_table;
如果快不了, 就分页吧。[/quote] 临时表没有设置字段和数据是怎么查出来的
acgl4 2018-01-27
  • 打赏
  • 举报
回复
引用 8 楼 yenange 的回复:
[quote=引用 7 楼 acgl4 的回复:]
[quote=引用 6 楼 yenange 的回复:]
你那个SQL, 最终的输出结果是多少行?

190219行[/quote]

这个输出的数据量这么大, 需要 4 秒钟不算多吧?

下面这种做法你看能不能快一点:
--1. 建立临时表
CREATE TEMPORARY TABLE tmp_table
SELECT a.custid
FROM g_customer_tb a
WHERE a.shopid IN (5, 7, 18, 29, 47, 77, 78, 86, 87, 88, 196, 197, 198, 199)
AND (a.size1 = 1 OR a.size2 = 1 OR a.size3 = 1);
CREATE INDEX ix_tmp_table ON tmp_table(custid);
--2. 连接查询
SELECT a.custid
FROM tmp_table a JOIN g_customer_tbdata b ON a.custid = b.custid
WHERE b.rq > '2016-01-29 00:00:00 ' AND b.rq < '2018-01-27 23:59:59'
GROUP BY b.custid
HAVING COUNT(b.id) = 1;
--3. 删除临时表;
DROP TABLE tmp_table;


如果快不了, 就分页吧。[/quote] 临时表怎么没创建成功,另外分页的话怎么写sql
吉普赛的歌 2018-01-27
  • 打赏
  • 举报
回复
引用 7 楼 acgl4 的回复:
[quote=引用 6 楼 yenange 的回复:] 你那个SQL, 最终的输出结果是多少行?
190219行[/quote] 这个输出的数据量这么大, 需要 4 秒钟不算多吧? 下面这种做法你看能不能快一点:
--1. 建立临时表
CREATE TEMPORARY TABLE tmp_table
SELECT a.custid
FROM   g_customer_tb a
WHERE  a.shopid IN (5, 7, 18, 29, 47, 77, 78, 86, 87, 88, 196, 197, 198, 199)
       AND (a.size1 = 1 OR a.size2 = 1 OR a.size3 = 1);
CREATE INDEX ix_tmp_table ON tmp_table(custid); 
--2. 连接查询
SELECT a.custid
FROM   tmp_table a JOIN g_customer_tbdata b ON  a.custid = b.custid
WHERE  b.rq > '2016-01-29  00:00:00 ' AND b.rq < '2018-01-27 23:59:59'
GROUP BY b.custid
HAVING COUNT(b.id) = 1;
--3. 删除临时表;
DROP TABLE tmp_table;
如果快不了, 就分页吧。
加载更多回复(7)

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧