存档

‘Tuning’ 分类的存档
10/03 06
没有评论 632 次查看

【译注】作为Oracle领域中神级的大牛Jonathan Lewis竟然也开始给SQL Server的用户写起文章来了,这实在是SQL Server社区的一个大好消息。现在这篇文章就是Jonathan写给SQL Server用户的第一篇文章,他文中通过一个详尽的例子给大家展示了一种高效SQL的可视化设计方法。正如文中所说的那样,这种设计高效SQL的方法的基本思想上是独立于数据库的,只有在实际进行SQL编码时才会涉及一些特定数据库的知识,因此这篇文章也是适合使用其它类型数据库的用户阅读。

有时候,在解决一个复杂的、有性能问题的查询时,把手从键盘上拿开,代之于拿起纸笔,会是个更好的方法。通过图表的方式把相关的表、连接、数据量以及索引都画出来,你就能更直观的找到可能会相对更有效率的查询表的路径。

人们经常说SQL是一种描述性的语言,你不需要告诉它怎么去取你要的数据,只需要描述清楚就行了。这点是没错的:只要描述好你要什么们你就能得到,但是却不能保证你能以你希望的速度和成本得到它。这就有点像你在一个陌生的城市打车,你把目的地告诉司机之后就只能寄希望于司机能给你选择一个最好的路线把你送到了,但是如果你没有提供给司机一些你期望走的路线的线索的话,很有可能你打车所花的钱和时间都会比你想象的多。

不管优化器能做到多好,都将会出现一些优化器算法无法应付你的要求的情况。这可能是现有统计数据的误导,或者是优化器针对你的数据做了些错误的假设,而你要做的就是找出一种能正确引导优化器的方法。

阅读全文…

10/03 03
没有评论 52 次查看

topTest environment

SELECT @@VERSION
---------------------------------------------------------------------------
Microsoft SQL Server 2005 - 9.00.3042.00 (Intel X86)
	Feb  9 2007 22:47:07
	Copyright (c) 1988-2005 Microsoft Corporation
	Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack 2)

topTest table script and some data

Table script:

USE tempdb
GO

DROP TABLE tmp
CREATE TABLE tmp (id INT, c CHAR(900))
CREATE CLUSTERED INDEX CI_C ON tmp(c)

DECLARE @i INT
SET @i=0
WHILE @i<100000

BEGIN
    INSERT INTO tmp(id, c)
    SELECT @i, CAST(RAND()*100000 AS VARCHAR)
    SET @i=@i+1
END

阅读全文…

10/02 28
没有评论 521 次查看



top实验环境和代码

本来实验的环境为

SELECT @@VERSION

---------------------------------------------------------------------------
Microsoft SQL Server 2005 - 9.00.3042.00 (Intel X86)
	Feb  9 2007 22:47:07
	Copyright (c) 1988-2005 Microsoft Corporation
	Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack 2)

测试数据库的代码为:

USE test
GO

DROP TABLE tmp

CREATE TABLE tmp (id INT, id2 INT, n int, c CHAR(4000))

DECLARE @i INT
SET @i=0
WHILE @i<1000000

BEGIN
    INSERT INTO tmp(id,id2,n, c)
    SELECT @i, @i, 1000, 'cccc'
    SET @i=@i+1
END

-- 建立索引,为的是在验证和修改数据时快点
CREATE INDEX ix_id2 ON tmp(id2)


topSQL Server 2000中的查询问题


top查询的阻塞问题

从SQL Server 2000过来的人都知道,在SQL Server 2000中有一个令人郁闷的问题,那就是锁对查询的阻塞,就是当你一个表上做了些DML操作之后,但是没有提交,这时候另外一个进程要查询这些修改的数据的时候,你的查询进程会被阻塞,直到执行DML操作进程提交完了以后,你的查询才能得以继续进行下去。在一个表修改很少的时候等会儿也就等会儿了,但是当一个表被频繁的修改的时候,这些锁带来的问题会让你的系统变得巨慢,甚至是死掉(由于SQL Server是利用字典表来管理锁的,锁多了之后系统挂起是很常见的)。

还好,微软对这个问题并不是没有解的,为了让查询不会DML操作所阻塞,他们提供了两个提示来解决这个问题,那就是NOLOCK(等同于READUNCOMMITTED)和READPAST这两个提示。NOLOCK就是著名的脏读提示了,在查询后面使用了WITH (NOLOCK)提示之后,查询将不再为未提交的DML操作所阻塞,但是却会同时把那些没有提交的数据给查询出来,这其实是非常的不好的;而READPAST带来的效果也没有更好,相比NOLOCK提示来说,READPAST提示会跳过那些被锁住的行,之查询那些没有被锁的数据行,也就是说当你一个表锁在表上的时候你再使用READPAST去查询的话将得到一个空的结果,同样的这种解决方法也是非常不好的,但是在2000的时代,也就只能这么的将就了。

阅读全文…

08/06 29
2 条评论 2,214 次查看



top前言

记得很早以前就有人跟我说过,在使用count的时候要用count(1)而不要用count(*),因为使用count(*)的时候会对所有的列进行扫描,相比而言count(1)不用扫描所有列,所以count(1)要快一些。当时是对这一结论深信不疑,虽然不知道为什么。今天正好有时间研究研究看count(*)和count(1)到底有没有性能差异。

我的测试环境是SQL Server 2005 SP2开发版。

在进行测试之前先建立一些测试的数据,代码如下:

create table test(a int, b varchar(100))
go
 
declare @n int
set @n = 1
while @n < 100000
begin
  
if @n%3 = 0
  
insert into test values (@n, null)
  
if @n%3 = 1
  
insert into test values (@n, str(@n))
  
if @n%3 = 2
  
insert into test values (@n, 'this is text')
  
set @n = @n+1
end

这里先说明一下,为了测试的目的,test表里面是故意没有加索引的。
阅读全文…

本文采用知识共享署名-非商业性使用-相同方式共享 3.0 Unported许可协议发布,转载请保留此信息
作者:马齿苋 | 链接:http://www.dbabeta.com/2008/sqlserver_howto_count.html
分类: SQL Server, Tuning 标签: ,

无觅相关文章插件,快速提升流量