none
SQL循环查询效率问题 RRS feed

  • 问题

  • 数据库有300多万条记录.每次查询大概要12-14秒左右.

    现在需要统计每天每个用户插入的总数.如何增强搜索效率.

    现在有20个用户.统计一次要循环20次.实际每次约2.5分钟左右.

    数据库为MySql.

    public int Count(string uid, string start, string end)
        {
            using (MySqlConnection MySqlCn = new MySqlConnection(cnStr))
            {
                MySqlCn.Open();
                MySqlDataAdapter da = new MySqlDataAdapter("select count(agent_no) from dtsys_log where agent_no='"+uid+"' and (start_time between '"+start+"' and '"+end+"')", MySqlCn);
                DataSet ds = new DataSet();
                da.Fill(ds);
                return  Convert.ToInt32(ds.Tables[0].Rows[0][0]);
            }
        }

    protected void Button2_Click(object sender, EventArgs e)
        {
            tb.Visible = false;
            string s = null;
            DateTime t = DateTime.Now;
            for (int i = 1; i < DropDownList1.Items.Count; i++)
            {
                s += DropDownList1.Items[i].Value.ToString() + "  " + Sr.Count(DropDownList1.Items[i].Value.ToString(), "2010-" + DropDownList3.SelectedValue + "-" + DropDownList4.SelectedValue + " " + DropDownList5.SelectedValue + "", "2010-" + DropDownList6.SelectedValue + "-" + DropDownList7.SelectedValue + " " + DropDownList8.SelectedValue + "") + "<br />";
            }
            Label2.Text = s + "<br />" + "用时:" + Sr.DateDiff(t, DateTime.Now);
        }

    • 已编辑 顾板 2010年5月11日 1:28
    2010年5月10日 6:19

答案

  • 你好,我认为效率的原因祝要出在访问数据库上。因此我觉得你可以将20次数据访问变为一次,也就是说你可以如下处理:

    string selectString = @"SELECT * FROM dbo.table_TEST WHERE (CLIENTID=" + clientID[0];
       for (int index = 1; index < clientID.Count; index++)
       {
        selectString += " OR CLIENTID=" + clientID[index];
       }
       selectString += ")";
       SqlDataAdapter testSqlDataAdapter = new SqlDataAdapter(selectString, sqlConnection);
       DataTable testDataTable = new DataTable();
       testSqlDataAdapter.Fill(testDataTable);
       // TODO: Add other operations

    这样,你可以从testDataTable中查询每个用户插入了多少。这样做的效率体现在两方面:

    1)访问数据库的时间减少(20次变为1次);

    2)更多的计算在内存中进行(内存和外存的速度差不是一个数量级);

    当然,你还需要在查询中添加一些其他的约束条件,这得看具体的数据了。

    还有一种做法就是批量检索,不过我做过相关的研究,你若有兴趣可以自己学下并分享下心得。

    • 已标记为答案 顾板 2010年5月13日 7:29
    2010年5月11日 1:53

全部回复

  • 你好,你的问题过于笼统,请补充一下,比如,你目前的sql语句是什么。
    邹俊才
    2010年5月10日 16:25
    版主
  • 你好,我认为效率的原因祝要出在访问数据库上。因此我觉得你可以将20次数据访问变为一次,也就是说你可以如下处理:

    string selectString = @"SELECT * FROM dbo.table_TEST WHERE (CLIENTID=" + clientID[0];
       for (int index = 1; index < clientID.Count; index++)
       {
        selectString += " OR CLIENTID=" + clientID[index];
       }
       selectString += ")";
       SqlDataAdapter testSqlDataAdapter = new SqlDataAdapter(selectString, sqlConnection);
       DataTable testDataTable = new DataTable();
       testSqlDataAdapter.Fill(testDataTable);
       // TODO: Add other operations

    这样,你可以从testDataTable中查询每个用户插入了多少。这样做的效率体现在两方面:

    1)访问数据库的时间减少(20次变为1次);

    2)更多的计算在内存中进行(内存和外存的速度差不是一个数量级);

    当然,你还需要在查询中添加一些其他的约束条件,这得看具体的数据了。

    还有一种做法就是批量检索,不过我做过相关的研究,你若有兴趣可以自己学下并分享下心得。

    • 已标记为答案 顾板 2010年5月13日 7:29
    2010年5月11日 1:53
  • 你好,根据你的需求,你可以把使用Sql实现这么一个视图,

    DateTime Id Count

    2010-01-01 1 100

    2010-01-02 2 200

    ......

    共365条数据(最多),然后绑定到界面就可以了。如果是月份,不需要日期,也是同理。


    邹俊才
    2010年5月11日 5:20
    版主
  • 上边两位给出了很好的方案,具体思路有三个:

    1.减少访问数据库的次数(最好所有操作一次完成)

    2.优化查询语句,可以使用存储过程代替SQL语句,省了编译的过程。

    3.优化表结构


    Skip to my lou
    2010年5月12日 6:28