怡红公子

无我原非你.从他不解伊.肆行无碍凭来去.茫茫着甚悲愁喜,纷纷说甚亲疏密.从前碌碌却因何,到如今.回头试想真无趣
随笔 - 48, 评论 - 529, 引用 - 42

导航

每月存档

最新留言

广告

【第1页/共4页,49条】
首页
前页
1
2008年01月22日
 在SQL Server 2000的时候,我们要想做Performance Tuning的时候,多半都必须用到Profiler或者SQL Tracer来跟踪,这东西一是结果分析起来麻烦,二是对系统资源消耗太大。在SQL Server 2005中,提供了动态管理视图和函数(Dynamic Management Views and Dynamic Management Functions),大大的方便了我们对系统运行情况的监控,故障诊断和性能优化。现在除了Debug以外,已经很少再对生产系统使用Profiler。顺便说一下,SQL Server 2008有一个更好,更强大的Data Collector,可以收集系统信息放入数据仓库,再进行分析的,那时候DBA就更方便了。

下面我会Step by step的介绍,如何使用DMV和DMF来诊断系统情况,介绍到的全部知识都来自于联机丛书(Books Online)。

 

Issue:在新上线一个系统后,我发现数据库服务器的CPU有所升高,达到20-30%,Peak time的时候甚至会达到50%。于是我打开性能监视器,发现SQL Logins/sec平均超过2000。那么,我希望知道,是哪些SQL语句调用次数如此频繁,找到了这些SQL语句之后,就可以进行有针对的优化。

全文地址:http://blog.myspace.cn/luke/archive/2008/01/22/400261243.aspx

posted on 2008-01-22 18:25:00 by luke  评论(7) 阅读(4879)

 
2007年12月07日

昨天有同事问我一个SQL语句,估计在不少地方会用到,所以在这里分享一下。

有一个对象,每个对象有0到N个属性,根据数据库设计的3NF,我们会设计一个这样的表

CREATE TABLE [dbo].[Objects](

 [ObjectID] [int] NOT NULL PRIMARY KEY,

 [ObjectNane] [varchar](100) NOT NULL

 )

 

CREATE TABLE [dbo].[ObjectAttributes](

 [ObjectID] [int] NOT NULL,

 [AttrName] [varchar](100) NOT NULL,

 [AttrValue] [varchar](500) NULL

)

ALTER TABLE ObjectAttributes ADD CONSTRAINT PK_ObjectAttributes PRIMARY KEY CLUSTERED

 (

 ObjectId,

 AttrName

 )

那么,我们希望找出Attr1 (AttrName) = "1" (AttrValue) 并且Attr2 (AttrName) = "2" (AttrValue)的记录。
比如,ObjectAttributes的内容为
1 Attr1 1
1 Attr2 2
2 Attr2 2
3 Attr1 1
4 Attr3 1

那么我们希望的结果是[dbo].[Objects]表中ObjectID为1的记录。
你会怎样写这个SQL语句呢?

我的同事想了一个办法,对ObjectAttributes 表查两次,然后Union All,Group By之后求Count。
完整的SQL语句如下:

SELECT o.*

FROM  Objects AS o INNER JOIN

      (SELECT     ObjectId

        FROM  (SELECT     ObjectId

                FROM          ObjectAttributes

                WHERE      (AttrName = 'Attr1') AND (AttrValue = '1')

                UNION ALL

                SELECT     ObjectId

                FROM         ObjectAttributes

                WHERE     (AttrName = 'Attr2') AND (AttrValue = '2')) AS M1

        GROUP BY ObjectId

        HAVING      (COUNT(*) = 2)) AS M2

ON o.ObjectID = M2.ObjectId

OK, 虽然看起来怪麻烦的,but it works.能管用就好,效率其实也不算差。就是如果判断条件再复杂一点,而且有交集并集的时候就不好办了。

其实,有一个更自然的写法可以解决这个问题。

SELECT *

FROM Objects AS o

WHERE EXISTS

        (SELECT * FROM ObjectAttributes

        WHERE ObjectId = o.ObjectID AND AttrName = 'Attr1' AND AttrValue = '1')

    AND EXISTS

        (SELECT * FROM ObjectAttributes

        WHERE ObjectId = o.ObjectID AND AttrName = 'Attr2' AND AttrValue = '2')

这样看起来是不是更易读呢?而且增加条件也很简单。

希望以上内容对你有帮助,方便的话,请帮我投2票,谢谢!投票需要有Myspace帐号,不过注册很容易的哦。

posted on 2007-12-07 13:22:00 by luke  评论(9) 阅读(4152)

 
2007年11月12日
http://blog.myspace.cn/1300316663/archive/2007/11/12/400072804.aspx

posted on 2007-11-12 18:29:00 by luke  评论(4) 阅读(5111)

 
2007年06月25日

MySpace招聘SQL专家,待遇超过Microsoft China,GTSC更加不在话下:p
如果您认为在下述方面有专长,请积极报名:  

1、工作地点:北京;
2、需要有VLDB或高并发数据库实战经验;
3、熟悉Microsoft SQLServer Database engine,了解Index, Lock等
4、有简单的英文沟通能力(至少技术方面要能够交流),可以去美国出差,最好会开车,在美国不会开车很不方便,而我就不会:'(
5、熟悉Replication优先
6、熟悉SSIS优先

请把个人简历发给我:klu@myspace.com

欢迎GTSC SQL Team的兄弟姐妹们跳槽:)

在MySpace,你可以接触到最大的互联网数据库之一。我们有超过200台SQL Server服务器,用户数超过160M。有竞争力的待遇,有挑战性的工作,MySpace.CN期待你的加入!

posted on 2007-06-25 11:36:00 by luke  评论(29) 阅读(7116)

 
2006年05月17日

 

我常用sp_spaceused来查看表所占的空间大小,可是一次只能看一个对象的。
今天有空写了个sp_spaceused2,可以同时看全部表的空间大小。

功能

显示当前数据库中某个类型表的行数、由它保留和使用的磁盘空间。

语法

sp_spaceused2 [[@type=] 'type']
    [,[@updateusage =] 'updateusage']

参数

[@type =] 'type'

是要显示的表的类型名称。可以是下列对象类型中的一种:
S = 系统表
U = 用户表
type 的数据类型是 varchar(2),默认设置为 'U'。

[@updateusage =] 'updateusage'

表示应在数据库内运行 DBCC UPDATEUSAGE。值可以是 truefalseupdateusage 的数据类型是 varchar(5),默认设置为 FALSE。

返回代码值

0(成功)或 1(失败)

结果集

返回针对指定类型的表的结果集。

列名 数据类型 描述
name nvarchar(128) 表名。
rows char(11) 表中现有的行数。
reserved varchar(18) 为表保留的空间总量。
data varchar(18) 表中的数据所使用的空间总量。
index_size varchar(18) 表中的索引所使用的空间总量。
unused varchar(18) 为表保留但尚未使用的空间总量。

注释

sp_spaceused 计算数据和索引使用的磁盘空间量以及当前数据库中的表所使用的磁盘空间量。

当指定 updateusage 时,Microsoft SQL Server 扫描数据库中的数据页,并就每个表使用的存储空间对 sysindexes 表作出任何必要的纠正。例如会出现这样一些情况:当除去索引后,表的 sysindexes 信息可能不是当前的。该进程在大表或数据库上可能要花一些时间运行。只有当怀疑所返回的值不正确,而且该进程对数据库中的其它用户或进程没有负面影响时,才应使用该进程。如果需要,可以单独运行 DBCC UPDATEUSAGE。

代码

http://www.sql-club.com/Luke/archive/2006/05/12/553.aspx

posted on 2006-05-17 10:37:00 by luke  评论(2) 阅读(6180)

 
2006年04月29日
http://www.sql-club.com/Sunwei/archive/2006/04/26/536.aspx

posted on 2006-04-29 13:59:00 by luke  评论(3) 阅读(8817)

 
在 SQL Server 2000 中,首先检查的是当前用户所拥有的架构,然后是 DBO 拥有的架构。
在 SQL Server 2005 中,每个用户都有一个默认架构,用于指定服务器在解析对象的名称时将要搜索的第一个架构。可以使用 CREATE USER 和 ALTER USER 的 DEFAULT_SCHEMA 选项设置和更改默认架构。如果未定义 DEFAULT_SCHEMA,则数据库用户将把 DBO 作为其默认架构。

posted on 2006-04-29 13:57:00 by luke  评论(8) 阅读(7332)

 
2006年01月10日

今天邹建问我一个问题,系统存储过程中的查询是在用户数据库中执行的,但是用户自己建立的存储过程却是在master中执行的(都是在master中建立的存储过程)。
例如:
use master
exec sp_helptext 'sp_spaceused'
拿到sp_spaceused的代码,把名字改为sp_spaceused2,再执行一次建立这个存储过程。
如:
use master
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS OFF
GO

create procedure sp_spaceused2 --- 1996/08/20 17:01
@objname nvarchar(776) = null,  -- The object we want size on.
@updateusage varchar(5) = false  -- Param. for specifying that
     -- usage info. should be updated.
as
……

然后在用户数据库中执行这两个存储过程。一样的代码,但是却得到不一样的结果。
USE STSDW
GO
EXEC sp_spaceused
EXEC sp_spaceused2


database_name                                                                                                                    database_size      unallocated space 
-------------------------------------------------------------------------------------------------------------------------------- ------------------ ------------------
STSDW                                                                                                                            13364.69 MB        7811.36 MB

 
reserved           data               index_size         unused            
------------------ ------------------ ------------------ ------------------
3896848 KB         3779384 KB         70872 KB           46592 KB

database_name                                                                                                                    database_size      unallocated space 
-------------------------------------------------------------------------------------------------------------------------------- ------------------ ------------------
STSDW                                                                                                                            22.00 MB           -3788.58 MB

 
reserved           data               index_size         unused            
------------------ ------------------ ------------------ ------------------
3896848 KB         3779384 KB         70872 KB           46592 KB

我们会发现其中database_size和unallocated space 的结果不一样,这是什么原因呢,SQL Server 的Bug?


原因是这样的,这是系统存储过程的特有功能,要想达到同样的功能,你除了名字要以sp_开头外(当然也必须是dbo的),还得使用sp_MS_marksystemobject 把你的存储过程标记为MS-shipped。
如:sp_MS_marksystemobject 'sp_spaceused2'

sp_MS_marksystemobject 也是一个未公开的存储过程,有兴趣可以自己看看它的代码,代码前一段如下:
-- FOR INTERNAL USE ONLY ... DO NOT DOCUMENT --
-- This procedure sets a bit in sysobjects.  This bit has no meaning, various
-- groups (starfigther, davinci, replication) use it for different things
-- MSQL makes no warranty, express or implied, on what objects will or will
-- not have this bit set.  Use at your own risk.

据说下一个版本的SQL会正式支持这个功能,不过目前还是未公开的。
某人给我的答复是这样的,Until then, this is undocumented and unsupported although "well known".
真是气死我了,although "well known"的,可是我压根就没听说过。

另外,Howard Yin建议说,最好不要把存储过程放到master里面,这样的话,安全和管理都会带来很多麻烦。比如说,软件的升级、打service pack、甚至是backup,都必须要考虑到你放到master里面的存储过程。
还有,SQL Server 2005提供了"execute as"的选项,如果你只是出于权限方面的考虑要把存储过程作为系统存储过程的话,可以考虑这个选项。

posted on 2006-01-10 13:58:00 by luke  评论(4) 阅读(5793)

 
2006年01月06日

原作(Wei.Xiao)
很多人都认为SQL Server的锁授予是FIFO(先进先出)以避免饥饿问题(又叫哲学家问题)的。想想吧,你在超市等待结帐的时候,如果别人可以随便插队的话,你还能离开超市吗?

我的朋友Santtu 是一个lock manager的专家,他告诉我SQL Server做得比这要聪明。FIFO有一个缺点,它并不总是允许最大的并发度。SQL Server 2005的lock manager就做到了在避免饥饿的情况下允许了尽可能大的并发度。

举个例子说明:Transaction T1在表Foo上有个IX lock,Transaction T2也在表Foo运行了一个查询并且指定了TABLOCK。显然T2会被T1所阻塞,S lock和IX lock是不能并存的。Transaction T3在表Foo上有个查询,但没有使用锁定提示。T3的IS请求就会在T2的S请求之前被授予,因为IS和IX, S都不冲突。但是如果Transaction T4要在表Foo上作一个update的话,就会被T2所阻塞,因为T4的IX lock和T2的S lock是不能并存的,T2先来,所以T2会先被执行。

posted on 2006-01-06 09:39:00 by luke  评论(3) 阅读(5162)

 
2005年09月21日

在SQL 2005中,字符串索引支持模糊匹配,如like '%abc%'的查询。
在SQL 2000中,字符串索引仅支持前导匹配,如like 'abc%'的查询。

这样不仅是在搜索时能够查找较少的page,更重要的是,SQL查询优化器能够准确的得到EstimateRows,就可以选择最适合的index,而SQL2000就只能瞎蒙。

不过呢,我在测试中发现这样的优化貌似不支持中文,于是和Access Method的人一起跟了一下,最后发现必须要是unicode类型的才能够支持中文。
该问题已经提交为bug,在SQL 2005 SP1中应当能够得到解决。

posted on 2005-09-21 11:58:00 by luke  评论(10) 阅读(5098)

 

在SQL 2005中,临时表和表变量的使用和以往没有什么区别。
不过呢,新的SQL OS还是为我们带来了一些内部的变化。

在SQL2000里面,如果执行计划关系到动态对象,如表变量、触发器等,计划就不会被缓存
SQL2005能缓存这些计划,避免了每次的重编译。

tempdb会缓存临时表和表变量(@t, #t)

而且SQL 2005对tempdb的改动比较大,也会提高临时表的性能,具体细节我不介绍了,不过呢,有两点建议:增加tempdb的大小,增加tempdb的文件数目(至少和CPU数目相同)。

关于SQL 2005对tempdb的改动,可以参见
http://blogs.msdn.com/weix/archive/2005/09/13/464907.aspx
[SQL Server 2005] TEMPDB optimization

posted on 2005-09-21 11:56:00 by luke  评论(3) 阅读(8249)

 

为什么要说呢?请参见http://www.sql-club.com/net2004/archive/2005/09/13/199.aspx

Partition一直就是一个很难用于实际应用的功能。为什么呢?选择分区字段是一个关键。必须要能使数据均匀的分散到不同的物理存储,又能使分区字段能够包含查询条件。
在smaple中大多是以ID或者Time作为分区字段,但是实际应用中,大部分查询都不会在这两个字段上。
以MSN为例,我登录的时候,要查询where username = 'luke@hotmail.com' --这不是我的passport
大部分的查询也是基于username的。
那么,我们以username为分区条件如何?可是这样会造成分区不均衡,显然s开头的就比x开头的要多许多。
当然,我们可以分析出字母序的分布概率,但是这是一个挺麻烦的工作,如果还考虑中文,就更加的麻烦了。
怎么办呢?MSN采用的方法是对username的hash值进行分区,值得借鉴哦~
hash的原理我不多介绍了,它有一个功能就是可以把字符串的hash值做到基本平均的分布。

SQL 2005自带一个hash函数,语法如下
HashBytes ( '', { @input | 'input' } )
支持MD2, MD4, MD5, SHA, or SHA1 算法
返回值varbinary (maximum 8192 bytes)

posted on 2005-09-21 11:55:00 by luke  评论(6) 阅读(4871)

 

内容有点长,只放个链接。

http://www.sql-club.com/luke/articles/160.aspx

posted on 2005-09-21 11:51:00 by luke  评论(0) 阅读(3913)

 

在SQL 2005中,建立新数据库时,checksum是默认选项,它可以提高硬件的可靠性。

使用DBCC CHECKDB ('database_name' | database_id) WITH PHYSICAL_ONLY 就可以检查checksum是否正确。当然,不用WITH PHYSICAL_ONLY 也行,不过会检查更多的东西,速度也会降低。

要关闭Checksum,可以使用ALTER DATABASE database_name
SET PAGE_VERIFY NONE,或者使用ALTER DATABASE database_name
SET PAGE_VERIFY TORN_PAGE_DETECTION

SQL 2000中,只对TORN_PAGE_DETECTION 进行处理,即每512字节放一个校验位,这样对资源使用更少,不过可靠性也更低。

posted on 2005-09-21 11:49:00 by luke  评论(3) 阅读(4992)

 
2005年03月31日

最近太懒,好久没写东西了,不过现在要开始动起来了:)

3月初MSDN Subscription发布了Yukon Feb CTP,预计5月发布Beta3,9月发布RTM

而且现在国内已经开始实际应用Yukon了,我会陆续post一些文章和经验的:)

posted on 2005-03-31 16:02:00 by luke  评论(10) 阅读(4095)

 
【第1页/共4页,49条】
首页
前页
1

Powered by: Joycode.MVC引擎 0.5.1.0