海量数据库查询语句
前端之家收集整理的这篇文章主要介绍了
海量数据库查询语句,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
以下代码说明了我们实例中数据库的“红头文件”一表的部分数据结构:
<DIV style="BORDER-RIGHT: #8a8a8a 1px solid; PADDING-RIGHT: 6px; BORDER-TOP: #8a8a8a 1px solid; PADDING-LEFT: 6px; FONT-SIZE: 12px; PADDING-BOTTOM: 6px; MARGIN: 1px; OVERFLOW: auto; BORDER-LEFT: #8a8a8a 1px solid; PADDING-TOP: 6px; BORDER-BOTTOM: #8a8a8a 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">CREATE<SPAN style="COLOR: #0000ff">TABLE[dbo].[TGongwen](<SPAN style="COLOR: #008000">--TGongwen是红头文件表名
[Gid][int]IDENTITY(1,1)<SPAN style="COLOR: #0000ff">NOT<SPAN style="COLOR: #0000ff">NULL,
<SPAN style="COLOR: #008000">--本表的id号,也是主键
[title]varcharCOLLATEChinese_PRC_CI_AS<SPAN style="COLOR: #0000ff">NULL,
<SPAN style="COLOR: #008000">--红头文件的标题
[fariqi][datetime]<SPAN style="COLOR: #0000ff">NULL,
<SPAN style="COLOR: #008000">--发布日期
[neibuYonghu]varcharCOLLATEChinese_PRC_CI_AS<SPAN style="COLOR: #0000ff">NULL,
<SPAN style="COLOR: #008000">--发布用户
[reader]varcharCOLLATEChinese_PRC_CI_AS<SPAN style="COLOR: #0000ff">NULL,
<SPAN style="COLOR: #008000">--需要浏览的用户。每个用户中间用分隔符“,”分开
)ON[PRIMARY]TEXTIMAGE_ON[PRIMARY]
<SPAN style="COLOR: #0000ff">GO
数据库中添加1000
@iint
@i=1
@i<=250000
Tgongwen(fariqi,neibuyonghu,reader,title)(,,,)
@i=@i+1
declare @i int
set @i=1
while @i<=250000
begin
insert into Tgongwen(fariqi,title) values('2004-9-16','',',,,,,,,,,,','25')
set @i=@i+1
end
GO
@hint
@h=1
@h<=100
@iint
@i=2002
@i<=2003
@jint
@j=0
@j<50
@kint
@k=0
@k<50
Tgongwen(fariqi,title)(cast(@ivarchar(4))++cast(@jvarchar(2))++cast(@jvarchar(2)),)
@k=@k+1
@j=@j+1
@i=@i+1
@h=@h+1
@iint
@i=1
@i<=9000000
Tgongwen(fariqi,title)(,添加的900万条记录')
@i=@i+1000000
通过以上语句,我们创建了2520042525200496200220031002500502004559001000
查询优化的首要前提。
index用户定义的存储在物理介质上的数据结构。当根据索引码的值搜索数据时,索引提供了对数据的快速访问。事实上,没有索引,数据库也能根据SELECT效果就越来越明显。注意,在这句话中,我们用了“适当”这个词,这是因为,如果使用索引时不认真考虑其实现过程,索引既可以提高也会破坏数据库的工作性能。
sql SERVERclustered indexnonclustered index
an文字母“azazhang内容。
内容本身就是一种按照一定规则排列的目录称为“聚集索引”。
快速地从自动中查到这个字。但您也可能会遇到您不认识的字,不知道它的发音,这时候,您就不能按照刚才的方法找到您要查的字,而需要去根据“偏旁部首”查到您要找的字,然后根据这个字后的页码直接翻到某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“张”字,我们可以看到在查部首之后的检字表中“张”的页码是672页码却是63页面是390页码。
方法进行排序。
查询2004112004101页码,然后再根据页码查到具体内容。
方法。
1
错误的,是对聚集索引的一种浪费。虽然sql SERVER
IDID自动增大的,步长一般为1自动化的实例中的列Gidsql SERVER数据库中按照ID
查询要求,迅速缩小查询范围,避免全表扫描。在实际应用中,因为ID自动生成的,我们并不知道每条记录的IDID查询。这就使让IDID用户经常修改记录内容,特别是索引项的时候会负作用,但对于查询速度并没有影响。
自动化系统中,无论是系统首页显示的需要用户签收的文件、会议还是用户进行文件查询等任何情况下进行数据查询都离不开字段的是“日期”还有用户本身的“用户名”。
自动化的首页会显示每个用户尚未签收的文件或会议。虽然我们的where用户尚未签收的情况,但如果您的系统已建立了很长时间,并且数据量很大,那么,每次每个用户打开首页的时候都进行一次全表扫描,这样做意义是不大的,绝大多数的用户1文件都已经浏览过了,这样做只能徒增数据库的开销而已。事实上,我们完全可以让用户打开系统首页时,数据库仅仅查询这个用户近3文件,通过“日期”这个字段来限制表扫描,提高查询速度。如果您的办公自动化系统已经建立的2首页显示速度理论上将是原来速度8
ID查询速度是没有这么高的,即使您在“日期”这个字段上建立的索引(非聚合索引)。下面我们就来看一下在1000查询的速度表现(325
1
Select gid,fariqi,title from tgongwen
128470128
2fariq
gid,titleTgongwen
fariqi>dateadd(day,-90,getdate())
用时:
5376354
3fariqi
gid,getdate())
用时:
24232
提取出来的都是25数据库真的有1000ID12显示。这也是我摒弃ID
方法是:在各个selectdeclare @d datetime
set @d=getdate()
select
select [(datediff(ms,@d,getdate())
2查询速度
23fariqi查询速度却有着天壤之别。所以,并非是在任何字段上简单地建立索引就能提高查询速度。
1000fariqi5003文件,这几个文件的发文日期就相同,这完全符合建立聚集索引要求的:“既不能绝大多数都相同,又不能只有极少数相同”的规则。由此看来,我们建立“适当”的聚合索引对于我们提高查询速度是非常重要的。
3查询速度的字段都加进聚集索引,以提高查询速度
查询时都离不开字段的是“日期”还有用户本身的“用户名”。既然这两个字段都是如此的重要,我们可以把他们合并起来,建立一个复合索引(compound index
查询速度,也有人感到迷惑:如果把复合的聚集索引字段分开查询,那么查询速度会减慢吗?带着这个问题,我们来看一下以下的查询速度(结果集都是25fariqi用户名neibuyonghu
1select gid,title from Tgongwen where fariqi>'2004-5-5'
查询速度:2513
2select gid,title from Tgongwen where fariqi>'2004-5-5' and neibuyonghu=''
查询速度:2516
3select gid,title from Tgongwen where neibuyonghu=''
查询速度:60280
查询条件和同时用到复合聚集索引的全部列的查询速度是几乎一样的,甚至比用上全部的复合索引列还要略快(在查询结果集数目一样的情况下);而如果仅用复合聚集索引的非起始列作为查询条件的话,这个索引是不起任何作用的。当然,语句12查询速度一样是因为查询的条目数一样,如果复合索引的所有列都用上,而且查询结果少的话,这样就会形成“索引覆盖”,因而性能可以达到最优。同时,请记住:无论您是否经常使用聚合索引的其他列,但其前导列一定要是使用最频繁的列。
1
提取25
select gid,title from Tgongwen where fariqi='2004-9-16'
3326
select gid,title from Tgongwen where gid<=250000
4470
1/4
2order by
select gid,title from Tgongwen order by fariqi
12936
select gid,title from Tgongwen order by gid
18843
order by3/1010
3搜索时间会按数据占整个数据表的百分比成比例减少,而无论聚合索引使用了多少个
select gid,title from Tgongwen where fariqi>'2004-1-1'
6343提取100
select gid,title from Tgongwen where fariqi>'2004-6-6'
3170提取50
select gid,title from Tgongwen where fariqi='2004-9-16'
3326数量一样,那么用大于号和等于号是一样的)
select gid,title from Tgongwen where fariqi>'2004-1-1' and fariqi<'2004-6-6'
3280
4 查询速度
10020041150505000
select gid,title from Tgongwen where fariqi>'2004-1-1' order by fariqi
6390
select gid,title from Tgongwen where fariqi<'2004-1-1' order by fariqi
6453
性能,但过多或不当的索引也会导致系统低效。因为用户在表中每加进一个索引,数据库就要做更多的工作。过多的索引甚至会导致索引碎片。
数据库能得到高性能的发挥。
数据库管理员,您还要多测试一些方案,找出哪种方案效率最高、最为有效。
sql
sqlsql SERVERsqlsql SERVER
select * from table1 where name='zhangsan' and tID > 10000
:
select * from table1 where tID > 10000 and name='zhangsan'
tID10000name='zhangsan'tID>10000查询结果。
sql SERVER查询分析优化器”,它可以计算出where搜索条件并确定哪个索引能缩小表扫描的搜索空间,也就是说,它能实现自动优化。
查询优化器可以根据where自动的进行查询优化,但大家仍然有必要了解一下“查询优化器”的工作原理,如非这样,有时查询优化器就会不按照您的本意进行快速查询。
查询分析阶段,查询优化器查看查询的每个阶段并决定限制需要扫描的数据量是否有用。如果一个阶段可以被用作一个扫描参数(SARG快速获得所需数据。
SARG搜索的一个操作,因为它通常是指一个特定的匹配,一个值得范围内的匹配或者两个以上条件的AND
< >
< >
Name=
>5000
5000<
Name= and >5000
SARG搜索的范围了,也就是sql SERVERWHERESARG
SARGSARG
1LikeSARG通配符的类型
name like % SARG
name like %,SARG
通配符%
2or
Name= and >5000 SARGName= or >5000 SARGor
3函数引起的不满足SARG
SARG包括非操作符的语句,如:NOT!=<>!<!>NOT EXISTSNOT INNOT LIKE函数。下面就是几个不满足SARG
ABS()<5000
Name like %
WHERE *2>5000
sql SERVERSARGsql SERVER
WHERE >2500/2
sql SERVER
4IN OR
Select * from table1 where tid in (2,3)
Select * from table1 where tid=2 or tid=3
tid
5NOT
6exists in
显示说,existsinnot existsnot innot查询,我们试验这次用sql SERVER自带的pubs数据库。运行前我们可以把sql SERVERstatistics I/O
1select title,price from titles where title_id in (select title_id from sales where qty>30)
'sales' 18 56 0 0
'titles' 1 2 0 0
2select title,price from titles where exists (select * from sales where sales.title_id=titles.title_id and qty>30)
'sales' 18 56 0 0
'titles' 1 2 0 0
existsin
7函数charindex()通配符%LIKE
LIKE加上通配符%函数charindex()LIKE错误的:
select gid,title,reader from tgongwen where charindex('',reader)>0 and fariqi>'2004-5-5'
7 4 7155 0 0
select gid,reader from tgongwen where reader like '%' + '' + '%' and fariqi>'2004-5-5'
7 4 7155 0 0
8unionor
whereorunionor
select gid,title from Tgongwen where fariqi='2004-9-16' or gid>9990000
68 1 404008 283 392163
select gid,title from Tgongwen where fariqi='2004-9-16'
union
select gid,title from Tgongwen where gid>9990000
9 8 67489 216 7499
unionor
or查询列是一样的话,那么用unionorunionor
select gid,title from Tgongwen where fariqi='2004-9-16' or fariqi='2004-2-5'
6423 2 14726 1 7176
select gid,title from Tgongwen wherefariqi='2004-2-5'
11640 8 14806 108 1144
9提取要按照“需多少、提多少”的原则,避免“select *
select top 10000 gid,title from tgongwen order by gid desc
4673
select top 10000 gid,title from tgongwen order by gid desc
1376
select top 10000 gid,fariqi from tgongwen order by gid desc
80
提取一个字段,数据的提取速度就会有相应的提升。提升的速度还要看您舍弃的字段的大小来判断。
10count(*)count()
*统计所有列,显然要比一个世界的列名效率低。这种说法其实是没有根据的。我们来看:
select count(*) from Tgongwen
1500
select count(gid) from Tgongwen
1483
select count(fariqi) from Tgongwen
3140
select count(title) from Tgongwen
52050
count(*)count()count(*)count(*) sql SERVER自动查找最小字段来汇总的。当然,如果您直接写count()
11order by
gidfariqi
select top 10000 gid,title from tgongwen
196 1 289 1 1527
select top 10000 gid,title from tgongwen order by gid asc
4720 1 41956 0 1287
select top 10000 gid,title from tgongwen order by gid desc
4736 1 55350 10 775
select top 10000 gid,title from tgongwen order by fariqi asc
173 1 290 0 0
select top 10000 gid,title from tgongwen order by fariqi desc
156 1 289 0 0
次数都是和“order by order by 查询速度是快得多的。
12TOP
查询和提取超大容量的数据集时,影响数据库响应时间的最大因素不是数据查找,而是物理的I/0
select top 10 * from (
select top 10000 gid,title from tgongwen
where neibuyonghu=''
order by gid desc) as a
order by gid asc
1000010数据库响应时间最大的因素是物理I/OI/O方法之一就是使用TOPTOPsql SERVER提取前几条或前几个百分比数据的词。经笔者在实践中的应用,发现TOP数据库ORACLEORACLE方法(如:rownumber解决。在以后的关于“实现千万级数据的分页显示存储过程”的讨论中,我们就将用到TOP
数据库中快速地查询出您所需要的数据方法。当然,我们介绍的这些方法都是“软”方法,在实践中,我们还要考虑各种“硬”因素,如:网络性能、服务器的性能、操作系统的性能,甚至网卡、交换机等。
分页显示存储过程
web 分页浏览功能必不可少。这个问题是数据库处理中十分常见的问题。经典的数据分页方法是:ADO 分页法,也就是利用ADO自带的分页功能(利用游标)来实现分页。但这种分页方法仅适用于较小数据量的情形,因为游标本身有缺点:游标是存放在内存中,很费内存。游标一建立,就将相关的记录锁住,直到取消游标。游标提供了对特定集合中逐行扫描的手段,一般使用游标来逐行遍历数据,根据取出数据条件的不同进行不同的操作。而对于多表和大表中定义的游标(大的数据集合)循环很容易使程序进入一个漫长的等待甚至死机。
分页检索时,如果按照传统的每次都加载整个数据源的方法是非常浪费资源的。现在流行的分页方法一般是检索页面大小的块区的数据,而非检索所有的数据,然后单步执行当前行。
页面大小和页码来提取数据的方法大概就是“俄罗斯存储过程”。这个存储过程用了游标,由于游标的局限性,所以这个方法并没有得到大家的普遍认可。
自动化实例写的分页存储过程:
pagination1
(@pagesizeint,页面大小,如每页存储20条记录
@pageindexint页码
)
nocounton
@indextable(idintidentity(1,1),nidint)
@PageLowerBoundint
@PageUpperBoundint
@PageLowerBound=(@pageindex-1)*@pagesize
@PageUpperBound=@PageLowerBound+@pagesize
rowcount@PageUpperBound
@indextable(nid)gidTGongwenfariqi>dateadd(day,-365,getdate())fariqi
O.gid,O.mid,O.title,O.fadanwei,O.fariqiTGongwenO,@indextabletO.gid=t.nid
t.id>@PageLowerBoundt.id<=@PageUpperBoundt.id
nocountoff