SQL 大佬来救命

342 天前
 0x19921213
select * from 
(select rownum as xh, t.* from 
(
	select * from (
	SELECT
			* 
		FROM
			q_materialfusion 
			
			where sjbj = '0' 
			and ( instr(mc, '1') > 0 
			OR instr(ssxmmc, '1') > 0 
		  OR instr(ssxtzc, '1') > 0
	    OR instr(xinghao, '1') > 0
      OR instr(gg, '1') > 0)
			order by nf desc, mc asc
	) where  rownum < 501
) t) where  xh >= 1;

这段 SQL 有优化空间吗,数据 200W ,返回需要 2 秒。

5366 次点击
所在节点    程序员
66 条回复
8355
342 天前
那么压力给到楼下的大佬, 我血压上来了.
tramm
342 天前
你这看着都头疼,看看楼下怎么说
BeautifulSoap
342 天前
问了 chatgpt ,它建议我用 LIKE
dizheyoulan
342 天前
不懂 sql ,问了 chatgpt ,它说改成这样
```
SELECT *
FROM (
SELECT ROWNUM AS xh, t.*
FROM (
SELECT *
FROM q_materialfusion
WHERE sjbj = '0'
AND '1' IN (mc, ssxmmc, ssxtzc, xinghao, gg)
ORDER BY nf DESC, mc ASC
) t
WHERE ROWNUM < 501
)
WHERE xh >= 1;
```
smallWang
342 天前
小白蹲一个 sql 大佬学习学习
raysonlu
342 天前
没有汇聚统计的逻辑,套这么多层干嘛?
siweipancc
342 天前
这查询,我只能用哇塞来形容。上全文搜索吧
sivacohan
342 天前
SELECT t.rownum as xh, t.*
FROM q_materialfusion as t
where t.sjbj = '0'
and t.rownum < 501
and t.xh >= 1
and (instr(t.mc, '1') > 0
OR instr(t.ssxmmc, '1') > 0
OR instr(t.ssxtzc, '1') > 0
OR instr(t.xinghao, '1') > 0
OR instr(t.gg, '1') > 0)
order by t.nf desc, t.mc asc;

这么写不可以吗?为什么要用多个子查询?
如果这么写可以,那就注意一下除了使用 instr 的部分其他查询条件最好有组合索引。
samv2
342 天前
where sjbj = '0' and concat(mc, ssxmmc, ssxtzc, xinghao, gg) like '%1%'
zjsxwc
342 天前
SELECT
rownum as xh, *
FROM
q_materialfusion

where sjbj = '0'
and (
instr(mc, '1') > 0
OR instr(ssxmmc, '1') > 0
OR instr(ssxtzc, '1') > 0
OR instr(xinghao, '1') > 0
OR instr(gg, '1') > 0
)
and rownum < 501
and rownum >= 1

order by nf desc, mc asc
JC1027
342 天前
```
SELECT
rownum as xh,
t.*
FROM (
SELECT *
FROM q_materialfusion
WHERE sjbj = '0'
AND (
mc LIKE '%1%'
OR ssxmmc LIKE '%1%'
OR ssxtzc LIKE '%1%'
OR xinghao LIKE '%1%'
OR gg LIKE '%1%'
)
ORDER BY nf DESC, mc ASC
)
WHERE rownum BETWEEN 1 AND 500;
```
samv2
342 天前
@samv2 #9 其实不确定算不算优化,手动狗头
bugsystem
342 天前
通意千问说改成这样
SELECT
t.rownum as xh,
t.*
FROM
(
SELECT
*
FROM
q_materialfusion
WHERE sjbj = '0'
AND ( instr(mc, '1') > 0
OR instr(ssxmmc, '1') > 0
OR instr(ssxtzc, '1') > 0
OR instr(xinghao, '1') > 0
OR instr(gg, '1') > 0)
ORDER BY
nf DESC,
mc ASC
) t
WHERE
t.rownum >= 501
zjsxwc
342 天前
yulgang
342 天前
>> ChatGPT 建议:

根据您提供的 SQL 查询语句,以下是一些可能的优化建议:

>1.创建索引:确保在 q_materialfusion 表上为用于过滤和排序的列( sjbj 、mc 、ssxmmc 、ssxtzc 、xinghao 、gg 、nf )创建索引。索引可以大大提高查询性能,特别是在大型数据集上。

>2.使用 UNION 替代 OR 条件:将 OR 条件改为使用 UNION 连接多个查询,每个查询只包含一个条件。这样可以更好地利用索引,提高查询性能。例如:

```
SELECT *
FROM q_materialfusion
WHERE sjbj = '0' AND instr(mc, '1') > 0
ORDER BY nf DESC, mc ASC
UNION
SELECT *
FROM q_materialfusion
WHERE sjbj = '0' AND instr(ssxmmc, '1') > 0
ORDER BY nf DESC, mc ASC
-- 添加其他条件的 UNION 查询
LIMIT 500;

```

>3.分页查询:如果您只需要返回前几行结果,可以使用分页查询,而不是检索全部数据。通过使用 ROWNUM (或类似的机制)进行分页,您可以避免一次性检索所有数据。例如,对于前 100 条结果:

```
SELECT *
FROM (
SELECT ROWNUM AS xh, t.*
FROM (
SELECT *
FROM (
SELECT *
FROM q_materialfusion
WHERE sjbj = '0'
AND (instr(mc, '1') > 0
OR instr(ssxmmc, '1') > 0
OR instr(ssxtzc, '1') > 0
OR instr(xinghao, '1') > 0
OR instr(gg, '1') > 0)
ORDER BY nf DESC, mc ASC
)
WHERE ROWNUM < 501
) t
)
WHERE xh BETWEEN 1 AND 100;

```

>4.批量处理:如果可能,可以考虑将大型查询拆分为多个较小的查询,并以批处理方式处理数据。这样可以减少单个查询的复杂性和负载,并且更容易进行并行处理。

请注意,优化查询性能是一个复杂的过程,需要结合实际数据和数据库配置进行调整。建议在生产环境中进行测试,并根据实际情况进行调整。
raysonlu
342 天前
我貌似第一次感受到论坛评论被 ai 污染的现象
locochen
342 天前
确定的限制条件可以放在最里面.

带入的查询条件,看是否可以通过语法解释后进入最里层的 select.这样就不会全表扫描.
magicyao
342 天前
几个 OR 没法优化,不知道为啥要这么设计,外面两层 select 都可以去掉,不过意义不大
0914xc
342 天前
找了半天,没找到微软小冰。
NoKey
342 天前
现在大家有问题,都是第一个问 AI 么🤣🤣🤣

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/941922

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX