Thursday, June 10, 2010

关于MSSQL I/O写入次数很高问题的分析


  1. 看一下task manager, 如果Sql Server 占有的内存即使在服务器最忙得时候都不超过2GB, 而你有4GB内存,可以考虑在Windows boot.ini启动文件中加入 /3GB变量。这样SqlServer就可以使用3GB的内存,多1GB意味着更大的缓存,可以不用到Disk取频繁读取了.

  2. 运行Perfmon,加入“Page Life Expectancy”如果这个值始终小于300秒,意味着你需要更大的内存,加入“Buffer Cache hit ratio” 如果这个值小于90%,意味着你需要更大的内存.加入 “Average Disk Queue length” 如果总是大于2,意味着磁盘操作需要排队完成。考虑升级存储设备.

  3. 运行profiler,跟踪器只选Stored procedure 和 T-Sql, 在Filter(过滤) tab, 选duration(时长)大于5000,这告诉跟踪器只捕捉运行时间超过5秒的程序。 你可以根据自己的情况调整这个变量。目的是找到制造麻烦的SQL.

  4. 运行sp_who2 ,看blk by 栏, 如果这栏不是空白, 有一个数字, 这就是造成阻塞(blocking)的线程id. 然后运行DBCC Inputbuffer(线程id), 你就可以看见这个线程在干什么。

  5. 确认你的客户端程序使用connection pooling,并在完成任务后关闭连接。Sqlserver默认255个连接,如果使用connection pooling, 这个值应该足够应付大多数情况。 如果你确认255不够,可以使用sp_configure重设这个值

  6. 以上都是在认为你完成数据库日常维护的前提下。 如果你不做日常维护,请立即开始。 经常用 DBCC indexDefrag. 每隔一段时间用DBCC DBREINDEX 重建 index. 你可以运行 DBCC Showcontig, 然后看Scan Density ,如果主要的大表Scan Density < 40%, 意味着你有严重的Fragmentation(碎片),该用DBCC REINDEX去整理了.
    DBCC SHOWCONTIG 执行后,结果全部类似下面片断
    [cc lang='text' line_numbers='false']DBCC SHOWCONTIG 正在扫描 'sysobjects' 表...
    表: 'sysobjects'(1);索引 ID: 1,数据库 ID: 12
    已执行 TABLE 级别的扫描。
    - 扫描页数.....................................: 586
    - 扫描扩展盘区数...............................: 91
    - 扩展盘区开关数...............................: 585
    - 每个扩展盘区上的平均页数.....................: 6.4
    - 扫描密度[最佳值:实际值]....................: 12.63%[74:586]
    - 逻辑扫描碎片.................................: 47.27%
    - 扩展盘区扫描碎片.............................: 97.80%
    - 每页上的平均可用字节数.......................: 2209.8
    - 平均页密度(完整)...........................: 72.70%[/cc]


写了个类,用于从结果中挑出需要重建索引的表并生成sql语句
[cc lang='java' ]import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Read a file and print, using BufferedReader and System.out
*/
public class CatFile {
public static void main(String[] av) {
av = new String[1];
av[0] = "e:\\DBCC Showcontig.TXT";
CatFile c = new CatFile();
if (av.length == 0) {
c.process(new BufferedReader(new InputStreamReader(System.in)));
}
else {
for (int i = 0; i < av.length; i++) { try { c.process(new BufferedReader(new FileReader(av))); } catch (FileNotFoundException e) { System.err.println(e); } } } } /** print one file, given an open BufferedReader */ public void process(BufferedReader is) { try { String inputLine; String tableName = ""; while ( (inputLine = is.readLine()) != null) { double density = 0; if (inputLine.indexOf("表: '" >= 0) {
tableName = inputLine.substring(inputLine.indexOf("'" + 1,
inputLine.indexOf("'(");
}
if (inputLine.indexOf("扫描密度" >= 0) {
density = Double.parseDouble(inputLine.substring(inputLine.indexOf(
"..: " + 4, inputLine.indexOf("%["));
if (density <= 40.0) {
//System.out.print("density--" + density);
//System.out.print(" ";
System.out.println("DBCC DBREINDEX (" + "'" + tableName +
"','',80)";
}
}
}
is.close();
}
catch (IOException e) {
System.out.println("IOException: " + e);
}
}
}[/cc]

No comments:

Post a Comment