﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-nighTuner &amp; Yuyu's Space-文章分类-Database</title><link>http://www.blogjava.net/nightuner/category/1024.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 06:54:49 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 06:54:49 GMT</pubDate><ttl>60</ttl><item><title>Mysql使用基础知识</title><link>http://www.blogjava.net/nighTuner/articles/3257.html</link><dc:creator>nighTuner</dc:creator><author>nighTuner</author><pubDate>Wed, 13 Apr 2005 18:03:00 GMT</pubDate><guid>http://www.blogjava.net/nighTuner/articles/3257.html</guid><wfw:comment>http://www.blogjava.net/nighTuner/comments/3257.html</wfw:comment><comments>http://www.blogjava.net/nighTuner/articles/3257.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/nighTuner/comments/commentRss/3257.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/nighTuner/services/trackbacks/3257.html</trackback:ping><description><![CDATA[<P>有很多朋友虽然安装好了mysql但却不知如何使用它。在这篇文章中我们就从连接MYSQL、修改密码、增加用户等方面来学习一些MYSQL的常用命令。 <BR>一、连接MYSQL。 <BR>格式： mysql -h主机地址 -u用户名 －p用户密码 <BR>1、例1：连接到本机上的MYSQL。 <BR>首先在打开DOS窗口，然后进入目录 mysqlbin，再键入命令mysql -uroot -p，回车后提示你输密码，如果刚安装好MYSQL，超级用户root是没有密码的，故直接回车即可进入到MYSQL中了，MYSQL的提示符是：mysql&gt; <BR>2、例2：连接到远程主机上的MYSQL。假设远程主机的IP为：110.110.110.110，用户名为root,密码为abcd123。则键入以下命令： <BR>mysql -h110.110.110.110 -uroot -pabcd123 <BR>（注:u与root可以不用加空格，其它也一样） <BR>3、退出MYSQL命令： exit （回车） <BR>二、修改密码。 <BR>格式：mysqladmin -u用户名 -p旧密码 password 新密码 <BR>1、例1：给root加个密码ab12。首先在DOS下进入目录mysqlbin，然后键入以下命令 <BR>mysqladmin -uroot -password ab12 <BR>注：因为开始时root没有密码，所以-p旧密码一项就可以省略了。 <BR>2、例2：再将root的密码改为djg345。 <BR>mysqladmin -uroot -pab12 password djg345 <BR>三、增加新用户。（注意：和上面不同，下面的因为是MYSQL环境中的命令，所以后面都带一个分号作为命令结束符） <BR>格式：grant select on 数据库.* to 用户名@登录主机 identified by "密码" <BR>例1、增加一个用户test1密码为abc，让他可以在任何主机上登录，并对所有数据库有查询、插入、修改、删除的权限。首先用以root用户连入MYSQL，然后键入以下命令： <BR>grant select,insert,update,delete on *.* to <A href='mailto:test1@"%'>test1@"%</A>" Identified by "abc"; <BR>但例1增加的用户是十分危险的，你想如某个人知道test1的密码，那么他就可以在internet上的任何一台电脑上登录你的mysql数据库并对你的数据可以为所欲为了，解决办法见例2。 <BR>例2、增加一个用户test2密码为abc,让他只可以在localhost上登录，并可以对数据库mydb进行查询、插入、修改、删除的操作（localhost指本地主机，即MYSQL数据库所在的那台主机），这样用户即使用知道test2的密码，他也无法从internet上直接访问数据库，只能通过MYSQL主机上的web页来访问了。 <BR>grant select,insert,update,delete on mydb.* to <A href="mailto:test2@localhost">test2@localhost</A> identified by "abc"; <BR>如果你不想test2有密码，可以再打一个命令将密码消掉。 <BR>grant select,insert,update,delete on mydb.* to <A href="mailto:test2@localhost">test2@localhost</A> identified by ""; </P>
<P>我们来看看MYSQL中有关数据库方面的操作。注意：你必须首先登录到MYSQL中，以下操作都是在MYSQL的提示符下进行的，而且每个命令以分号结束。 </P>
<P>一、操作技巧 <BR>1、如果你打命令时，回车后发现忘记加分号，你无须重打一遍命令，只要打个分号回车就可以了。也就是说你可以把一个完整的命令分成几行来打，完后用分号作结束标志就OK。 <BR>2、你可以使用光标上下键调出以前的命令。但以前我用过的一个MYSQL旧版本不支持。我现在用的是mysql-3.23.27-beta-win。 </P>
<P>二、显示命令 <BR>1、显示数据库列表。 <BR>show databases; <BR>刚开始时才两个数据库：mysql和test。mysql库很重要它里面有MYSQL的系统信息，我们改密码和新增用户，实际上就是用这个库进行操作。 <BR>2、显示库中的数据表： <BR>use mysql； ／／打开库，学过FOXBASE的一定不会陌生吧 <BR>show tables; <BR>3、显示数据表的结构： <BR>describe 表名; <BR>4、建库： <BR>create database 库名; <BR>5、建表： <BR>use 库名； <BR>create table 表名 (字段设定列表)； <BR>6、删库和删表: <BR>drop database 库名; <BR>drop table 表名； <BR>7、将表中记录清空： <BR>delete from 表名; <BR>8、显示表中的记录： <BR>select * from 表名; </P>
<P>三、一个建库和建表以及插入数据的实例 <BR>drop database if exists school; //如果存在SCHOOL则删除 <BR>create database school; //建立库SCHOOL <BR>use school; //打开库SCHOOL <BR>create table teacher //建立表TEACHER <BR>( <BR>id int(3) auto_increment not null primary key, <BR>name char(10) not null, <BR>address varchar(50) default '深圳', <BR>year date <BR>); //建表结束 <BR>//以下为插入字段 <BR>insert into teacher values('','glchengang','深圳一中','1976-10-10'); <BR>insert into teacher values('','jack','深圳一中','1975-12-23'); </P>
<P>注：在建表中（1）将ID设为长度为3的数字字段:int(3)并让它每个记录自动加一:auto_increment并不能为空:not null而且让他成为主字段primary key（2）将NAME设为长度为10的字符字段（3）将ADDRESS设为长度50的字符字段，而且缺省值为深圳。varchar和char有什么区别呢，只有等以后的文章再说了。 （4）将YEAR设为日期字段。 <BR>如果你在mysql提示符键入上面的命令也可以，但不方便调试。你可以将以上命令原样写入一个文本文件中假设为school.sql，然后复制到c:\下，并在DOS状态进入目录\mysql\bin，然后键入以下命令： <BR>mysql -uroot -p密码 &lt; c:\school.sql <BR>如果成功，空出一行无任何显示；如有错误，会有提示。（以上命令已经调试，你只要将//的注释去掉即可使用）。 </P>
<P>四、将文本数据转到数据库中 <BR>1、文本数据应符合的格式：字段数据之间用tab键隔开，null值用\n来代替. <BR>例： <BR>3 rose 深圳二中 1976-10-10 <BR>4 mike 深圳一中 1975-12-23 <BR>2、数据传入命令 load data local infile "文件名" into table 表名; <BR>注意：你最好将文件复制到\mysql\bin目录下，并且要先用use命令打表所在的库 。 </P>
<P>五、备份数据库：（命令在DOS的\mysql\bin目录下执行） <BR>mysqldump --opt school&gt;school.bbb <BR>注释:将数据库school备份到school.bbb文件，school.bbb是一个文本文件，文件名任取，打开看看你会有新发现。 </P>
<P>后记：其实MYSQL的对数据库的操作与其它的SQL类数据库大同小异，您最好找本将SQL的书看看。我在这里只介绍一些基本的，其实我也就只懂这些了，呵呵。最好的MYSQL教程还是“晏子“译的“MYSQL中文参考手册“不仅免费每个相关网站都有下载，而且它是最权威的。可惜不是象"PHP4中文手册"那样是chm的格式，在查找函数命令的时候不太方便。</P><img src ="http://www.blogjava.net/nighTuner/aggbug/3257.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/nighTuner/" target="_blank">nighTuner</a> 2005-04-14 02:03 <a href="http://www.blogjava.net/nighTuner/articles/3257.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MS SQL Server调优</title><link>http://www.blogjava.net/nighTuner/articles/3248.html</link><dc:creator>nighTuner</dc:creator><author>nighTuner</author><pubDate>Wed, 13 Apr 2005 17:48:00 GMT</pubDate><guid>http://www.blogjava.net/nighTuner/articles/3248.html</guid><wfw:comment>http://www.blogjava.net/nighTuner/comments/3248.html</wfw:comment><comments>http://www.blogjava.net/nighTuner/articles/3248.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/nighTuner/comments/commentRss/3248.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/nighTuner/services/trackbacks/3248.html</trackback:ping><description><![CDATA[<P>在建立一个新的实例后，mssql会先生成master,model,msdb,tempdb 四个系统数据库,就master，model，msdb这三个系统数据库建议最后与用户数据库分开存储，一般系统数据库应该特别小心。主数据库保护着自己及其他数据库的分类信息、配置信息、用户数据库信息、作业信息、还有数据库模版。一旦系统数据库受到破坏，整个实例就有可能崩溃。</P>
<P>而tempdb这个临时数据库，它对性能的影响较大。tempdb和其他数据库一样可以增大，可以缩小。当数据文件需要增长的时候，通常不能保持剩余部分的连续性。这时文件就会产生碎片，这种碎片会造成性能下降。这种碎片属于外来性碎片。要阻止在tempdb中产生外来性碎片，必须保证有足够的硬盘空间。一般将tempdb的容量放到平均使用容量。而你也应该允许tempdb自动增长，比如你有个一个超大的join操作，它建立了一个超过tempdb容量的时候，该查询将失败。你还要设置一个合理的单位增长量。因为如果你设得太小，将会产生许多外来性碎片，反而会占用更多资源。sqlserver调优最有效的做法之一，就是把争夺资源的操作独立出去。tempdb就是一个需要独立出去的部分而tempdb和其他系统库一样是公用的，是存取最可能频繁的库，所有处理临时表、子查询、GROUP BY、排序、DISTINCT、连接等等。它最适合放到一个具有快速读写能力的设备上。比如RAID0卷或RAID0+1卷上。移动tempdb的方法：</P>
<P>1、用Enterprise Manager或sp_helpdb查看tempdb现在存放的位置<BR>2、用<BR>alter database tempdb modify file(name='tempdev',filename='newpath\newfilename',size=20mb)<BR>alter database tempdb modify file(name='templog',filename='newpath\newfilename',size=20mb)<BR>3、关闭sqlserver重起<BR>4、删掉旧的tempdb文件<BR>而我们在建立一个用户数据库的时候，也要考虑数据文件放哪、日志文件放哪、用几个数据文件。数据文件访问当然希望尽可能快。但是通常数据文件对于用户具有极其重要，所以一般考虑数据保护和高可用性，将它们放到RAID5中。日志文件呢，它记录了对数库所做的历史记录，它用于校验数据库中的数据完整性。它也应该和你的数据文件分开存储，和数据文件一样事务日志也是会自动增长的，当空间够大的时候事务记录操作得很快。而这时你觉得它太大了，去缩减它，，而你再一操作数据库，它要花费时间去分配空间，如果你不让写入，数据库将被置疑。所以这不是个好办法。你应该通过文件截断或日志备份，这样可以从事务日志中释放空间。这里说的空间是指日志文件内部可用空间，而不是日志文件的大小。日志管理器每秒传输操作可以顺序写入60KB。对调整事务日志最好的建议是放到一个最快的阵列上，一个办法是RAID0+1。增加一个文件组中的文件数，往往会改善性能，因为会创建更多的线程来扫描数据文件。又比如你有两个上百万的表，分别建立索引。如果你放在一个文件组中性能会受很大影响。而比如你建立4个数据文件每个物理磁盘上建立一个，而且把数据文件放到单独的数据文件组,而把每个索引也放到它自己的文件组中。查询性能会显著提高<BR>使用DBCC命令来优化<BR>D B C C命令就像名字的含义一样，本来是为了检查数据库的一致性。但后来D B C C命令变<BR>成了一些有用的函数。D B C C命令的使用有一些限制。以下就是所支持的命令列表。<BR>D B C C {<BR>CHECKALLOC[(database_name [, NOINDEX])] |<BR>C H E C K C ATALOG [(database_name)] |<BR>C H E C K TABLE (table_name[,NOINDEX | index_id]) |<BR>CHECKDB [(database_name [, NOINDEX])] |</P>
<P>dllname (FREE) |<BR>INPUTBUFFER (spid) |CHECKIDENT [(table_name)] |<BR>D B R E PAIR (database_name,DROPDB [,NOINDEX])] |<BR>M E M U S A G E |<BR>N E WALLOC[|(database_name[,NOINDEX])] |<BR>OPENTRAN ({database_name} | {database_id})<BR>[WITH TA B L E R E S U LTS] |<BR>OUTPUTBUFFER(spid) |<BR>PERFMON |<BR>P I N TABLE (database_id,table_id) |<BR>S H O W _ S TATISTICS (table_name,index_name) |<BR>SHOWCONTIG(table_id,[index_id]) |<BR>SHRINKDB (database_name[,new_size[,'MASTEROVERRIDE')]]) |<BR>SQLPERF ({IOSTATS | LRUSTATS | NETSTATS | RASTATS[,CLEAR]} | {THREADS} |<BR>{ L O G S PACE}) |<BR>T E X TALL [({database_name | database_id} [,FULL | FAST])] |<BR>T E X TALLOC [({table_name | table_id}[,FULL | FAST])] |<BR>TRACEOFF(trace#) |<BR>TRACEON(trace#) |<BR>T R A C E S TATUS (trace#[,trace#]) |<BR>U N P I N TABLE(database_id,table_id) |<BR>U P D ATEUSAGE({0 | database_name} [,table_name [,index_id]]) |<BR>[WITH NO_INFOMSGS]<BR>有些D B C C命令需要数据库名，而有些需要数据库I D。你可以观看SQL Server的错误日志<BR>或运行如下的查询并在S e l e c t语句中用数据库名代替d b n a m e就可得到数据库的I D。</P>
<P>存储还有一点就是最后使用NTFS格式，NTFS格式的读取速度比FAT32快。其实这是属于SQLServer调优中，系统优化的部分。</P>
<P>说到这补充一点，一般影响SQLServer调优的有4个部分：系统调优占2.5%，数据库调优占17.5%，设计调优占20%，程序可调优的空间最大占60%。呵呵，但是一般DBA拿到一个系统的时候，设计调优和程序可调优是不可控的，应为他不可能去改买来的软件。</P>
<P>面先看看索引步骤，这些有利于大家对索引的认识。<BR>一、堆<BR>1、sqlserver在sysindexes表中查到对应的数据行<BR>2、读取indid值(应为堆没有索引所以是0)后，sqlserver开始读取firstIAM值，获取堆的IAM的第一页(8KB)的位置。(IAM将堆的各个区域联接在一起)<BR>3、sqlserver根据IAM提供的区域地址，一个区域一个区域的查找，一个数据页一个数据页的查找，直到获取所需的数据为止。</P>
<P>二、簇索引<BR>1、sqlserver在sysindexes表中查到对应的数据行，找到indid为1后，sqlserver开始读取root列的值。(列值是根页面的地址)<BR>2、找到根页面后开始搜索，比如要搜索的表是10条记录一页，这里是找“1981”这个值，将索引的值“1981”与根页面的索引比较。由于“1981”是在1900到2000之间。所以sqlserver开始搜索1900所在的中间页。<BR>3、找到“1900”所在的中间页后，将索引值“1981”继续与中间页的索引比较，由于“1981”是在1980到1990之间。所以sqlserver开始搜索1980所在的数据页。(注意这一步是根据中间页找数据页)<BR>4、找到“1980”所在的数据页后，将索引值“1981”继续与数据页的索引比较，很快就可以在这个数据页上找到“1981”的数据行了。</P>
<P>三、非簇索引<BR>1、sqlserver在sysindexes表中查到对应的数据行，找到indid为后，值为2到251后，sqlserver开始读取root列值。<BR>2、找到根页面后，将“1981”与根页面的索引比较，由于“1981”是在1900到2000之间。所以sqlserver开始搜索1900所在的中间页。(注意这一步是根据中间页找叶页面)<BR>3、找到中间页后，将索引值“1981”继续与中间页的索引比较，由于“1981”是在1980到1990之间。所以sqlserver开始搜索1980所在的叶页面。<BR>4、找到“1980”所在的叶页面后，继续叫索引值“1981”与叶页面上的关键字比较，在叶页面上找到关键字为“1981”的数据行ID。<BR>5、根据数据行ID提供的数据页和数据行信息，定位到指定的数据页和数据行，找到“1981”这条记录是“晶”的。<BR>堆在数据表小于8K的时候访问速度最快，它不需要去找索引，应为当你的数据本来就在一个页里也没有必要用索引。簇索引，在使用簇索引查询的时候，区块查询是最快的，如用between，应为他是物理连续的，你应该尽量减少对它的updaet,应为这可以使它物理不连续。非簇索引与物理顺序无关，设计它时必须有高度的可选择性，可以提高查询速度，但对表update的时候这些非簇索引会影响速度，且占用空间大，如果你愿意用空间和修改时间换取速度可以考虑。如果在视图上建立索引,那视图的结果集就会被存储起来，对与特定的查询性能可以提高很多，但同样对update语句时它也会严重减低性能，一般用在数据相对稳定的数据仓库中。好，为什么update会影响索引，打个比方:1 2 3 4 5 6 7 8 |1 2 ..它们在insert后是物理连续的，每个数字代表一条数据，一条数据1K，分割符前正好填满一页，在做查询时由于不需要指针跳转，所以效率是最佳的，而这是update了3把它的数据量改为了1.2K，超过原来的一页(8K)的大小，这时sqlserver会： 1 2 4 5 6 7 8|1 2.....| 3(1.2k) 将3放到最后面可以插入的空间去。而2的指针还是指向3,如果这时你再检索，当检索到2的时候，物理指针将跳转到3上，然后再跳转回4。如果看懂的话，应该明白了为什么不提倡update索引过的列，不提倡使用varchar类型的列当索引。应为varchar是变长的，如果你频繁的update它，你的索引会事得其反。而sqlserver里也提供了填充因子来减少来自这方面的影响，比如你的因子为20%，当插入数据时,发现这个页底于20%的可用空间，sqlserver不会再继续插入这一页而是申请新的一页存储如：1 2 3 4 5 6 | 7 8 1 2 .. 当你再update 3为1.2K的时候将不会将3分到其他页上。那是不是填充因子越大越好呢，不是的，如果太大，浪费空间不算什么，主要是会影响查询效率，应为在查询过程中最大消耗是来自于读取新页。所以你必须根据你的实际情况，适当设置。</P>
<P>维护索引也是很重要的，update是一个破坏索引的方式，它不但使指针跳转，而且使数据冗余，产生了许多碎片。你就需要用DBCC INDEXDEFRAG 整理指定的表或视图的聚集索引和辅助索引碎片。另外我们知道索引一般会有一个根比如有1 2 3 4 5，那建立索引的时候根是3，取中间的。当我们开始向这个表填加数据，比如这个列是一个顺序增长的如1 2 3 4 5...10000，这时发生了根节点偏移，应为根还是3而，就好象这个树变成了单边树，只往一个方向长。而这个现象是很常见的。而维护索引也很简单，最有效的办法是用DBCC DBREINDEX重建索引。<BR>SQL Server在每次重启服务时会重建tempdb数据库</P>
<P>如果系统运行过程中 tempdb因需要自动增长了，SQL Serve不会记住增长后的大小，重启服务后仍然恢复到初始大小，<BR>但如果用户使用了手工调整tempdb的大小，重启服务SQL Server会把tempdb重建为用户指定大小</P>
<P>测试示例</P>
<P>tempdb初始化大小为8MB</P>
<P>1)使tempdb自动增长<BR>select b.* into #t from sysprocesses a,sysobjects b<BR>重启后使用sp_helpdb 'tempdb'<BR>可以看到tempdb又恢复到8MB<BR>2) 用户使用Alter Database调整为100MB,</P>
<P>USE master<BR>GO<BR>ALTER DATABASE tempdb<BR>MODIFY FILE<BR>(NAME = tempdev,SIZE = 100MB)</P>
<P>重启服务后使用查看tempdb大小就为100MB</P>
<P>以下查询可以看到tempdb的变化<BR>select a.filename,a.name,a.size*8.0/1024.0 as originalsize_MB,<BR>f.size*8.0/1024.0 as currentsize_MB<BR>from master..sysaltfiles a join tempdb..sysfiles f on a.fileid=f.fileid<BR>where dbid=db_id('tempdb')<BR>and a.size&lt;&gt;f.size</P>
<P>总结:<BR>当系统自动调整tempdb大小时，对文件的读写将暂时的阻塞<BR>所以如果我们预知tempdb将会增加到某个大小时，可以自行调整，从而避免性能下降</P>
<P>减少执行过程中的重新编译</P>
<P>对有的查询而言，由编译过程产生查询计划所付出的代价占是执行整个查询所付出代价的一部分，所以使用事先编译好的计划可以节省时间，避免重新编译的情况</P>
<P>存储过程recompile的原因</P>
<P>referenced objects, running the sp_recompile system stored procedure against<BR>a table referenced by the stored procedure, <BR>restoring the database containing the stored procedure or any object referenced by the stored procedure, or the stored <BR>procedures plan dropping from the cache. </P>
<P><BR>删除或者重建过程<BR>在过程里使用with recomplie语句，或者在执行时使用<BR>使用sp_recomlile 使存储过程在下次运行时重新编译<BR>恢复数据库时<BR>或者存储过程计划从高速缓存中移出<BR>如果过程引用表的有足够的数据发生变化<BR>如果用户在DDL语句中插入DML语句<BR>SET CONCAT_NULL_YIELDS_NULL </P>
<P>While these recompilations are normal and cannot be helped, DBAs and developers <BR>should not assume that all stored procedure recompiles are for normal reasons and should take a proactive approach to determine if they have a recompile problem. </P>
<P><BR>可以使用profile跟踪过程的重新编译<BR>新建一跟踪<BR>事件删除全部，选择存储过程下的 SP:Recompile, SP:Starting, and SP:Completed under Stored Procedure events<BR>sP:StmtStarting and SP:StmtCompleted 可以查看哪些语句引起recompile<BR></P><img src ="http://www.blogjava.net/nighTuner/aggbug/3248.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/nighTuner/" target="_blank">nighTuner</a> 2005-04-14 01:48 <a href="http://www.blogjava.net/nighTuner/articles/3248.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>