标签:
由于项目更新了一大版本,过不了多久就会进行一次SQL语句查询的优化任务,由运维部分导出一份历史查询SQL语句日志给开发部门做优化分析工作。以前写过一个日志分析的工具,可以不是很好,所以最近又花了几天时间,完善了这个工具。下面,我来说一下,开发历程:
一、任务分析:
1、工具界面:
2、具体需求:分类统计、忽略参数、调试错误
3、预想效果:参数部分用 ? 代替,工具效果展示:
二、开发编码:(读取(bgWorke),写入)
1、变量设置:
static string resultFile;//日志文件地址 static Dictionary<string, int> Seldic, Updic, Insertdic, Deletedic, Othdic, keysDic;//Dic static Regex patLike, patEqual, patNumber, patQo, patBE, patManySpace, patOther, patLine, patKeys;//正则 int type = 5;//SQL 语句类型 patLike = new Regex(@"(\s+like\s+)\‘(.|\n)+?\‘"); patEqual = new Regex(@"=\s*\‘(.|\n)+?\‘"); patNumber = new Regex(@"\d+"); patQo = new Regex(@"\s+(in)\s*\((\?\,)+"); patBE = new Regex(@"\BETWEEN\s+\‘(.)+?\‘\s+(AND)\s+\‘(.)+?\‘"); patManySpace = new Regex(@"\s{2,}");//空格 patOther = new Regex(@"=\s*(‘‘|null)"); patLine = new Regex(@"\d+\s+((Init|Connect|Quit|Statistics)|(Query\s+(COMMIT|BEGIN|Show|SET|GRANT|flush)))", RegexOptions.IgnoreCase); patKeys = new Regex(@"(\d+\s*(\d{2}\:*)+)\d+\s+(query)"); keysDic = new Dictionary<string, int>();//类型字典 keysDic.Add("s", 1); keysDic.Add("i", 2); keysDic.Add("u", 3); keysDic.Add("d", 4);
2、读取日志:
private void ReadLog() { int i = 0; StreamReader sr = new StreamReader(resultFile, Encoding.UTF8); String line; string strSQL = string.Empty; int IsNumberCount = 0;// int lineNumber = 0;//本行行号 string Number = string.Empty; while ((line = sr.ReadLine()) != null) { if (patLine.IsMatch(line)) { continue; } line = line.ToLower(); line = line.Replace("\t", ""); if (line.IndexOf("query") > -1) { IsNumberCount += 1; if (lineNumber == 1 && IsNumberCount == 2) { analyzeSQLString(strSQL); IsNumberCount = 1; strSQL = ""; } if (lineNumber != 1 && IsNumberCount == 1) { if (!string.IsNullOrEmpty(strSQL)) { analyzeSQLString(strSQL); strSQL = ""; } } lineNumber = 1; strSQL = patKeys.Replace(line, "").Trim(); } else { strSQL += " " + line.Trim(); lineNumber++; IsNumberCount = 0; } i++; if (ckDebug.Checked) { Thread.Sleep(1); bgWorker.ReportProgress(i, strSQL); } } if (strSQL != "") { analyzeSQLString(strSQL); } sr.Close(); sr.Dispose(); }
3、语句分析
private void analyzeSQLString(string strSQL) { keysDic.TryGetValue(Convert.ToString(strSQL[0]), out type); if (ckIgnore.Checked) { if (type == 2) { if (strSQL.IndexOf(" values ") > 0) { strSQL = strSQL.Substring(0, strSQL.IndexOf(" values ")); } } else { strSQL = patManySpace.Replace(strSQL, " ");//多余空格 strSQL = patOther.Replace(strSQL, "=?");//处理 name=‘‘ 的情况 strSQL = patBE.Replace(strSQL, "between ? and ?"); strSQL = patNumber.Replace(strSQL, "?"); strSQL = patLike.Replace(strSQL, " like ?"); strSQL = patEqual.Replace(strSQL, "=?"); strSQL = patQo.Replace(strSQL, "in ("); } } }
3、写入文件
private void WriteLog(Dictionary<String, int> data, Dictionary<String, int> sort, StreamWriter sw, int i) { if (data.Count > 0) { sort = data.OrderByDescending(o => o.Value).ToDictionary(o => o.Key, p => p.Value); foreach (KeyValuePair<string, int> de in sort) { sw.Write(de.Value.ToString().PadRight(7, ‘ ‘) + " " + de.Key + "\r\n"); } } }
4、最终效果
链接:http://share.weiyun.com/b3b2a221231994207b8219cdc685970b (密码:8p1i)
三、最后感想:
说实话,这东西用处不是很大,但是这做这个东西的时候,加深了对正则表达式的学习。
标签:
原文地址:http://www.cnblogs.com/lifuzhen/p/4962579.html