我正在运行的查询出现MySQL超时问题。这是一个简单的查询,但即使在MySQL编辑器中,也需要5分钟左右才能完成。我希望你们可能知道更好的方法来解决这个超时问题。
string processedCONString = "SERVER=localhost;" +
"DATABASE=discovery;" +
"UID=;" +
"PASSWORD=;"+
"connection timeout=500000";
MySqlConnection processCON = new MySqlConnection(processedCONString);
string mySQLCOMMAND = "update "+ siteString+"_discovery "+
"set processed = b'0' "
+"WHERE URL not in (select URL from live)";
MySqlCommand mysqlprocessCmdInsertItem = new MySqlCommand(mySQLCOMMAND, processCON);
processCON.Open();
mysqlprocessCmdInsertItem.ExecuteNonQuery();
processCON.Close();
是的,UID和密码在此处留空,但不在代码中。
此外,随着此数据库的增长,查询将花费更长时间。
答案 0 :(得分:5)
尝试索引siteString +“_discovery”返回的表中的URL列。
更新
另请注意,在where子句和INNER JOIN中指定语句的顺序非常重要。您希望了解何时语句将导致对每行执行操作,或者是否将提前完成操作然后应用于行。有几条规则可以在网上得到很好的记录。其他答案在这里提供了一些好的建议。此外,当我在一家大型代理商工作时,我总是将我的SQL脚本运行到我们的dba之后,然后强烈惩罚我,并抱怨软件开发人员总是打破他的m * ** f *** 数据库。如果你有这样的人,他们通常是一个很大的帮助,因为他们已经记住了所有这些规则而我们没有。
Google:“sql查询最佳做法”,你会发现过多的信息。这是一个链接,
答案 1 :(得分:1)
Jonathan Henson回答是一个很好的选择+1。
如果仍然不够,您可以尝试按部件处理。想象一下,你有一个ID,你可以将你的代码放在一个cicle中,并在每次迭代中处理1000(或你认为合适的数字)项目。
答案 2 :(得分:0)
也许我已经到了,但试试这个sql ......
"UPDATE " + siteString + "_discovery as d " +
" SET d.processed = b'0' " +
" WHERE d.URL IN (SELECT URL from live where URL = d.URL) ";
不是评估子查询中的整个select,而是过滤它,以便在尝试评估父语句中where条件时不返回每一行。
虽然,子查询将针对返回的每一行运行,所以我们应该完全删除子查询并让连接处理这个。因为我们只想在LIVE表中找到我们可以找到的URL,所以加入它们应该是平坦的子查询...
"UPDATE d " +
" SET d.processed = b'0' " +
" FROM " + siteString + "_discovery as d " +
" JOIN live as l " +
" ON d.URL = l.URL";
这个特定的更新是在SQL Server上测试的,而不是MySql,但你可能需要调整事件的顺序来转换它,我不是百分百肯定,有人可以确认吗?
答案 3 :(得分:0)
如果您对异常感到恼火,那么
mysqlprocessCmdInsertItem.CommandTimeout=1000;
可能会有所帮助(或超时的其他大数字)。命令超时30秒默认值(仅在网络读取计数中花费的时间)。
答案 4 :(得分:0)
我知道这个帖子很古老,Mohgeroth在正确的轨道上,但对于mysql,查询看起来像这样...
update siteX_discovery
left join live on live.URL = siteX_discovery.URL
set processed = b'0'
where live.URL is null
当然,正如乔纳森指出的那样,你需要索引,否则无论你做什么都会很慢。
总而言之,索引在很长一段时间内已经足够好了,但如果你的表变大,那么消除该子查询会产生显着的差异。