我有2个表,一个有200万个,另一个有3000万个记录, 我需要比较两个表上的记录,但这非常慢。
有人可以就如何提高速度提出建议吗?
<?php
$con = mysql_connect("localhost","root","password");
mysql_select_db("DMBONE", $con);
$result = mysql_query("SELECT * FROM sucid where priority=''");
while($row = mysql_fetch_array($result))
{
$result1 = mysql_query("SELECT count(*) FROM bills_logic where month(tdate)=8 and x1=".$row[0]."");
if($row1 = mysql_fetch_array($result1))
{
if($row1[0]==0)
{
echo $row[0]." DEAD\r\n";
mysql_query("update sucid set priority='DEAD' where bid=".$row[0]."") or die(mysql_error());
}
else
{
echo $row[0]." ".$row1[0]."\r\n";
mysql_query("update sucid set priority='".$row1[0]."' where bid=".$row[0]."") or die(mysql_error());
}
}
}
?>
CREATE TABLE `sucid` (
`bid` varchar(500) NOT NULL,
`priority` varchar(500) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `bills_logic` (
`bid` int(11) NOT NULL AUTO_INCREMENT,
`num` varchar(500) NOT NULL,
`stat` varchar(500) NOT NULL,
`tdate` varchar(500) NOT NULL,
`x1` varchar(500) NOT NULL,
`amt` varchar(500) NOT NULL DEFAULT '30',
PRIMARY KEY (`bid`)
) ENGINE=InnoDB AUTO_INCREMENT=35214848 DEFAULT CHARSET=latin1
上面的是表的create table语句。
答案 0 :(得分:0)
我建议创建索引,特别是用于分隔搜索的值。在您的特定情况下,我首先要为字段优先级创建索引。
有关mysql如何处理索引的更多信息,请查看here。
答案 1 :(得分:0)
是的,你可能有一个很大的问题。速度和查询性能取决于:
希望所有数据库专家都不将blob包含在作为主表的同一个表中。当我们讨论要获取的数百万个数据时,这是所有数据库的一个大问题。将blob数据分开总是作为最佳实践更好。
这只是其他信息,希望它可以帮助其他人。
答案 2 :(得分:0)
你找到了世界上做join
的最慢方法。你可能会以老式的方式(但只是时髦地使用mysqli
)更乐意这样做:
<?php
$mysqli = new mysqli("localhost","root","password","database");
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
$sql = "update sucid
left join (
select count(*) as priority, x1
from bills_logic b
where month(tdate)=8
group by x1
) bg
on bg.x1 = sucid.bid
set sucid.priority = coalesce(bg.priority,'DEAD');"
if ($mysqli->query($sql) === TRUE) {
printf("I'm done already. This was fast, wasn't it?\n");
}
else {
echo "Something went wrong: " . $mysqli->error . "\n";
exit();
}
?>
你可能想在bills_logic.x1
上添加一个索引,虽然这里没有太多帮助。
你应该真正修复你的专栏,例如tdate
不应该是varchar(500)
。如果您的任何行具有无效日期,则更新将完全失败。使用正确的数据类型可防止您使用无效值。 num
,stat
和amt
听起来可能是int
(或者decimal
),x1
也许。如果您将priority
替换为int
,则DEAD
- 列也可以0
。