码迷,mamicode.com
首页 > 数据库 > 详细

MySQL执行语句日志分析工具

时间:2015-11-13 18:56:20      阅读:350      评论:0      收藏:0      [点我收藏+]

标签:

  由于项目更新了一大版本,过不了多久就会进行一次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)

三、最后感想:

  说实话,这东西用处不是很大,但是这做这个东西的时候,加深了对正则表达式的学习。

MySQL执行语句日志分析工具

标签:

原文地址:http://www.cnblogs.com/lifuzhen/p/4962579.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!