存档
估计很多人在学习SQL表连接的时候都会被各种类型的表连接搞得稀里糊涂的,现在好了,有了下面的图,就可以很直观的区分各种表连接了。
作者:马齿苋 | 链接:http://www.dbabeta.com/2011/visual-sql-joins.html
《深度对比Oracle与SQL Server》PDF版下载地址
在线版
PDF版
CSDN下载:http://download.csdn.net/source/2314938
ITPUB下载:http://www.itpub.net/thread-1299140-1-1.html
作者:马齿苋 | 链接:http://www.dbabeta.com/2010/oracle-sql-server-comparison_pdf-download.html
topError Log与Alert Log
SQL Server维护着一个运行期间的操作日志,这个日志包括了启动信息、恢复事件、用户操作、备份信息、配置变更、非法登录、错误、警告信息等等。每次SQL Server服务启动的时候都会生成一个新的日志文件,这个日志就是SQL Server中著名的Error Log。
这个日志是DBA进行错误诊断的一个主要的信息来源。默认情况下SQL Server会保留6个日志文件,老的文件先被先行删掉,这个默认值是可以修改的。当前使用错误日志的名字是ERRORLOG(没有扩展名),紧随其后的名字为ERRORLOG.1,接着是ERRORLOG.2,依此类推。

Oracle中与SQL Server Error Log等价的是Alert Log文件,Alert Log包含了数据启动关闭、实例恢复、配置变更、内部错误、初始化参数等等信息。
和SQL Server不一样的是,Oracle Alert Log不会在每次实例启动的时候都创建一个新的文件,不管这个Alert Log文件会增长到多大,Oracle都只会维护这一个文件。Alert Log的名字为alert_<instance>.log,其中的<instance>是Oracle实例名。Oracle DBA和SQL Server DBA一样是通过这么一个Alert Log来获得错误诊断所需要的信息。

SQL Server的Error Log和Oracle的Alert Log都是ASCII文本格式的,可以使用任意的文本编辑器打开(译注:Oracle 11g开始提供XML格式的错误日志文件,需要使用ADR打开查看,此前生成文本格式文件的功能依然保留着)。SQL Server Management Studio(Windows界面)也可以用来查看Error Log,Oracle中则可以通过Enterprise Manager Database Control(Web界面)来查Alert Log的内容。
SQL Server的Error Log文件存放的地方由注册表键值决定,默认的位置通常是SQL Server安装目录中的LOG目录之下。而Oracle中Alert Log的位置由初始化参数
BACKGROUND_DUMP_DEST决定,默认情况下通常是在$ORACLE_HOME下面的bdump目录中。
译者:马齿苋 | 链接:http://www.dbabeta.com/2010/oracle-sql-server-comparison-iv.html
作者:Sadequl Hussain | 原文:http://www.sql-server-performance.com/articles/dba/oracle_sql_server_comparison_iv_p1.aspx
top启动与配置参数
在SQL Server安装的时候,同时也会往Windows注册表里面添加一些记录,这些注册表键值指定了实例所需要的各种参数。比如,有的注册表键值指定了错误日志的保存目录,另外的指定了默认的备份目录等等。SQL Server在运行的过程中会使用到这些注册表键值。另外还能给SQLSERVER.EXE指定一些启动参数,包括追踪标志(trace flags),这些附加的参数决定了实例启动之后的行为。除了注册表键值和启动参数之外,SQL Server还包括大量的内部配置参数,用于对实例进行调优。比如说“max server memory”就属于这些参数之一,它可用来调整实例所能使用的最大内存。不用说了,这些系统配置参数也是保存在系统元数据表(system metadata tables)中的。
下面例举的方法都可以用来修改SQL Server配置参数:
- 使用系统存储过程sp_configure
- 使用Management Studio或是Enterprise Manager的服务器属性对话框
- 使用各种层面(facets)组件(2008)或外围应用配置器(Surface Area Configuration)工具(2005)
Oracle的配置参数来自两个对于启动实例和打开数据库都是非常重要的操作系统文件,第一个文件是初始化参数文件(initialisation parameter file),第二个是控制文件(control file)。初始化参数文件所包含的参数决定怎么样创建实例。记住Oracle实例只包含内存结构和后台进程。参数文件包含的值决定了Oracle要给自己分配多少内存,可以同时有多少用户可以连接到数据库等等。Oracle在读取到这个文件之后才会在内存中建立数据库实例。
参数文件可以是一个纯文本的ASCII文件或者是二进制文件,纯文本参数文件称为pfile,名字为init<SID>.ora,其中的SID就是实例的SID了(参照“实例名与SID”小节)。二进制参数文件称为spfile,名字为spfile<SID>.ora。纯文本参数文件和二进制参数文件之间最大的差别就是当使用pfile的时候,Oracle只在实例启动的时候读取一次,后续对pfile的修改都要等到实例重启之后才能生效。而使用spfile时,Oracle能在实例运行期间修改其内容。在本文写作之时,Oracle 11g已经有超过250个的初始化参数了,不过还好,作为DBA你是不需要挨个的去设置这些参数的,你只需要配置那么十来个参数就可以保证实例正常使用了,大多数参数值都会使用Oracle默认的设定值。你可以通过Oracle Enterprise Manager Database Control(稍后细说)或者是手工的修改这些初始化参数,手工方法即时通过ALTER SYSTEM命令来修改spfile,使用pfile时,DBA可以直接使用文本编辑器进行修改。(译注:不管是使用pfile还是spfile,都能够使用ALTER SYSTEM命令修改这些参数,只是使用pfile时这些参数的修改是无法保存下来的,同时能修改的也只是一些动态的参数,而使用spfile则可以将这些修改保存到spfile文件中永久保留下来。)
控制文件是实例启动之后Oracle第二个要读取的文件。控制文件所存放的位置也是由参数文件中的参数来指定的。控制文件是一个很小的二进制文件,它包含了与数据库相关的关键的信息,其中包括数据文件和重做日志文件的名字与位置、表空间信息以及检查点信息,Oracle使用控制文件来找到数据文件,然后才能打开供用户访问。控制文件损坏或者是不存在的话数据库都是无法打开的。考虑到控制文件的重要性,通常的做法都是设置多份相同的控制文件拷贝以保证容错能力,多路控制文件中的所有控制文件都会同时的被更新。
最后,第三种Oracle数据库要使用的文件就是密码文件(password file)了,这个文件保存了拥有启动和关闭数据库权限的用户帐户的用户名和密码,稍后会细说。
译者:马齿苋 | 链接:http://www.dbabeta.com/2010/oracle-sql-server-comparison-iii.html
作者:Sadequl Hussain | 原文:http://www.sql-server-performance.com/articles/dba/oracle_sql_server_comparison_iii_p1.aspx
top数据库实例结构
当Oracle实例启动之后,所看到的就是在服务器内存上的一个个不同内存块加上产生的与这些内存交互的后台进程。Oracle文档将这些内存结构和进程收的很详细。
由Oracle实例所占用的内存块成为SGA(System Global Area),它的大小可以通过调整Oracle初始化参数(initialisation parameter)进行修改,在SGA里边至少会创建3个不同的区域,它们分别是:
- 数据块缓存区(Database Buffer Cache)
- 这里缓存的是数据块。和SQL Server一样,用户不会直接的访问数据文件上的数据:当读取数据时,相关的数据块会从数据文件中拷贝到内存中;修改数据时也是修改内存中的数据,然后再由单独的进程将数据缓存区中被修改的数据写入到数据库中。
- 重做日志缓存(Redo Log Buffer)
- SGA中的这个区域连续的记录着数据缓存区数据修改的记录,重做日志缓存中的内容会被写入到在线日志文件中去。
- 共享池(Shared Pool)
- SGA中有一大块的内存用作共享池,共享池等价于SQL Server中的执行缓存(Procedure Cache)。它的主要作用就是缓存数据库中最近执行过的SQL语句。共享池由下面的模块组成:
- 数据字典缓存(Dictionary Cache)
- 数据字典缓存缓存了Oracle最近使用的数据字典信息。
- 库缓存(Library Cache)
- 这个区域包含了最近执行的SQL和PL/SQL语句和对应的执行计划。SQL区还能进一步分成共享区和私有区:共享SQL区保存的语句可以由多个用户使用而私有区保存的则是跟各个连接对应的绑定变量的信息。PL/SQL是Oracle对于行业标准SQL的程序扩展,当PL/SQL程序执行时,它的代码会拷贝到库缓存中的共享PL/SQL区中。除了缓存执行代码和执行计划外,库缓存还包含锁、阀以及字符集等信息。
根据你所使用的组件的不一样,Oracle的SGA中也可能存在其它一些可选的内存区域。在Oracle中使用Java应用时要使用到Java池(Java Pool),Oracle内置的备份恢复工具RMAN(Recovery Manager)要用到大池(Large Pool),当使用Oracle高级队列机制时要用到流池(Steams Pool)。
译者:马齿苋 | 链接:http://www.dbabeta.com/2010/oracle-sql-server-comparison-ii.html
作者:Sadequl Hussain | 原文:http://www.sql-server-performance.com/articles/dba/oracle_sql_server_comparison_ii_p1.aspx
一般的公司通常会在他们的信息系统架构中引入多种数据库平台,同时引入三到四种不同的RDBMS解决方案的中大型公司也并不少见,当然这些公司里面的DBA们通常也需要同时拥有管理多种不同平台的技能了。
只在一种平台上展开工作的数据库专家们也通常会期待着在他们的下一份工作中能学到点不一样的东西,那些有勇气的人们则愿意花时间、金钱和精力去学习新的东西,也有其他因为换了新公司或者是为了找新的工作而去学习新的系统的人们,毋庸置疑的一点就是公司老板和人力专家们会更加青睐于那些拥有多个领域经验的求职者。
依我个人的经验来看,在学习一个新的数据平台的时候,最好的方法就是在新的环境中去发现那些你已知的东西,这样学习起来会简单很多。当然,当中也会遇到一些全新的概念需要去学习,或者是忘掉一些你现在已知的概念,但不管怎么说你不是从零开始的。比如说一个做SQL Server开发人员在要写Oracle存储过程的时候可能会先去找那些内置的函数然后比较它们之间不同点,她也可能会去比较变量声明以及错误处理的异同。
本系列文章中我将尝试对Microsoft SQL Server和Oracle RDBMS(以10g及以后的版本为主)进行一个深入的比较。我会主要集中于这两种数据库之间架构上的比较,当然不要期望我会给你一个详尽的比较清单,但是我会尽我所能的让你看清这两种当今世上应用最广的数据库之间的相同和相异之处。本文是以一个SQL Server DBA的角度去构思和写作的,不过相信这对Oracle专家门了解SQL Server这一面也是很有参考价值的。
废话少说,开工吧。
译者:马齿苋 | 链接:http://www.dbabeta.com/2010/oracle-sql-server-comparison-i.html
作者:Sadequl Hussain | 原文:http://www.sql-server-performance.com/articles/dba/oracle_sql_server_comparison_p1.aspx
topNULL是什么
NULL,字典的解释是空值。
如果你对ASCII表还有印象的话应该记得ASCII的第一个字符就是NUL(00),在C/C++语言中它被用来作为一个字符串的结尾,通常表示为”\00″,因此从ASCII码的意义上说NULL还是算是“看得见摸得着”的东西。
但是当NULL放到SQL当中的时候,它的意义就会有些不同了,在SQL中,NULL就是空,但又不仅仅是空,实际上NULL代表着的是未知、是空洞、是虚无缥缈。这一点SQL Server和Oracle都达成了共识,且看SQL Server中对于NULL的描述:
空值一般表示数据未知、不适用或将在以后添加数据。
在Oracle中的描述也是类似的:
null
Absence of a value in a column of a row. Nulls indicate missing, unknown, or inapplicable data.
既然NULL代表的是未知,那当然就不能用常规等于或者是不等于来判断说一个值是否为NULL了,当然也就不能说NULL等于NULL,因为你是不能去判断两个未知是否相等,那是没有意义的。
作者:马齿苋 | 链接:http://www.dbabeta.com/2010/null-in-sqlserver-and-oracle.html
【译注】作为Oracle领域中神级的大牛Jonathan Lewis竟然也开始给SQL Server的用户写起文章来了,这实在是SQL Server社区的一个大好消息。现在这篇文章就是Jonathan写给SQL Server用户的第一篇文章,他文中通过一个详尽的例子给大家展示了一种高效SQL的可视化设计方法。正如文中所说的那样,这种设计高效SQL的方法的基本思想上是独立于数据库的,只有在实际进行SQL编码时才会涉及一些特定数据库的知识,因此这篇文章也是适合使用其它类型数据库的用户阅读。
有时候,在解决一个复杂的、有性能问题的查询时,把手从键盘上拿开,代之于拿起纸笔,会是个更好的方法。通过图表的方式把相关的表、连接、数据量以及索引都画出来,你就能更直观的找到可能会相对更有效率的查询表的路径。
人们经常说SQL是一种描述性的语言,你不需要告诉它怎么去取你要的数据,只需要描述清楚就行了。这点是没错的:只要描述好你要什么们你就能得到,但是却不能保证你能以你希望的速度和成本得到它。这就有点像你在一个陌生的城市打车,你把目的地告诉司机之后就只能寄希望于司机能给你选择一个最好的路线把你送到了,但是如果你没有提供给司机一些你期望走的路线的线索的话,很有可能你打车所花的钱和时间都会比你想象的多。
不管优化器能做到多好,都将会出现一些优化器算法无法应付你的要求的情况。这可能是现有统计数据的误导,或者是优化器针对你的数据做了些错误的假设,而你要做的就是找出一种能正确引导优化器的方法。
译者:马齿苋 | 链接:http://www.dbabeta.com/2010/designing-efficient-sql.html
作者:Jonathan Lewis | 原文:http://www.simple-talk.com/sql/performance/designing-efficient-sql-a-visual-approach/
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
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的时代,也就只能这么的将就了。
作者:马齿苋 | 链接:http://www.dbabeta.com/2010/sql-server-2005-consistent-read.html

近期评论