Php MySQL中的长更新查询

Php MySQL中的长更新查询,php,mysql,Php,Mysql,我必须运行一些mysql更新查询,它们需要很长时间才能运行。我使用一个PHP脚本,但每次更新需要40到600毫秒,一般在250毫秒左右 我试图尽可能地优化,但脚本仍然需要30多分钟才能运行(两个表中都有20000个条目) 这是我的PHP脚本和更新查询的一部分: if (mysql_num_rows($Rmaster) == 1) { //Start time $Qchange_name = 'UPDATE slave SET NewAreaName = "'.$Amaster['Area

我必须运行一些mysql更新查询,它们需要很长时间才能运行。我使用一个PHP脚本,但每次更新需要40到600毫秒,一般在250毫秒左右

我试图尽可能地优化,但脚本仍然需要30多分钟才能运行(两个表中都有20000个条目)

这是我的PHP脚本和更新查询的一部分:

if (mysql_num_rows($Rmaster) == 1) {
//Start time
    $Qchange_name = 'UPDATE slave SET NewAreaName = "'.$Amaster['AreaName'].'" WHERE Dialcode = "'.$Amain['Dialcode'].'" ORDER BY Dialcode ASC LIMIT 1 ';
    $Rchange_name = mysql_query($Qchange_name, $link);
//end time = 40 to 600ms
}
我的SELECT查询速度很快,两个表中的拨号代码都有索引

这些是我的表格(简化):

还有什么我能让它更快的吗

PHP:5.3.4

MySQL:5.1.53

(我将在本周末首先尝试PDO解决方案并更新帖子)谢谢

更新: 我用PDO尝试了以下两种不同的查询:

$Qchange_name = $pdo->prepare('UPDATE slave SET NewAreaName = ? WHERE DIalcode = ?');
$Qchange_name = $pdo->prepare('REPLACE INTO slave SET NewAreaName = ? AND Dialcode = ?');
但是仅仅做150行的foreach大约需要18秒

在我的主要循环中,我会:

$L4 = array(); // Before the loops
else if ($countQmaster1 == 1) {
   $L4[] = array($Amaster1['AreaName'], $Amain['Dialcode']);        
}
然后在循环结束时:

foreach ($L4 as $b){
    $Qchange_name->execute($b); 
}
我也有拨号代码作为主要索引

我做错什么了吗

更新:隔离查询

下面是创建表和代码的文件。我隔离了查询并减少了脚本,但运行150行仍然需要17秒

你觉得有什么不对吗?你得到同样的结果吗

PHP代码 或

Mysql表下载或下载

我在考虑缓冲区问题?我在本地机器上运行,我得到一些快速和慢速更新

1 was executed in 38.87 ms 
2 was executed in 33.05 ms 
3 was executed in 33.17 ms 
4 was executed in 91.42 ms 
5 was executed in 36.17 ms 
6 was executed in 30.23 ms 
7 was executed in 33.15 ms 
8 was executed in 33.21 ms 
9 was executed in 33.22 ms 
10 was executed in 42.72 ms 
11 was executed in 32.12 ms 
12 was executed in 33.04 ms 
13 was executed in 33.14 ms 
14 was executed in 33.2 ms 
15 was executed in 33.2 ms 
16 was executed in 33.16 ms 
17 was executed in 33.25 ms 
18 was executed in 33.2 ms 
19 was executed in 33.12 ms 
20 was executed in 33.25 ms 
21 was executed in 33.15 ms 
22 was executed in 33.21 ms 
23 was executed in 33.16 ms 
24 was executed in 41.54 ms 
25 was executed in 74.79 ms 
26 was executed in 129.35 ms 
27 was executed in 77.65 ms 
28 was executed in 34.06 ms 
29 was executed in 33.21 ms 
30 was executed in 33.2 ms 
31 was executed in 33.17 ms 
32 was executed in 140.5 ms 
33 was executed in 34.04 ms 
34 was executed in 41.53 ms 
35 was executed in 33.23 ms 
36 was executed in 33.14 ms 
37 was executed in 158.06 ms 
38 was executed in 149.8 ms 
39 was executed in 278.14 ms 
40 was executed in 154.52 ms 
41 was executed in 149.71 ms 
42 was executed in 91.45 ms 
43 was executed in 274.55 ms 
44 was executed in 149.77 ms 
45 was executed in 278.46 ms 
46 was executed in 1055.73 ms 
47 was executed in 280.42 ms 
48 was executed in 149.85 ms 
49 was executed in 154.48 ms 
50 was executed in 178.14 ms 
51 was executed in 158.06 ms 
52 was executed in 433.23 ms 
53 was executed in 149.22 ms  
54 was executed in 166.41 ms 
55 was executed in 41.5 ms 
56 was executed in 33.21 ms 
57 was executed in 41.52 ms 
58 was executed in 33.16 ms 
59 was executed in 33.19 ms 
60 was executed in 49.8 ms 
61 was executed in 33.21 ms 
62 was executed in 33.16 ms 
63 was executed in 41.55 ms 
64 was executed in 33.13 ms 
65 was executed in 58.25 ms 
66 was executed in 33.12 ms 
67 was executed in 41.52 ms 
68 was executed in 33.15 ms 
69 was executed in 33.21 ms 
70 was executed in 41.51 ms 
71 was executed in 33.18 ms 
72 was executed in 33.19 ms 
73 was executed in 41.52 ms 
74 was executed in 33.25 ms 
75 was executed in 33.15 ms 
76 was executed in 41.58 ms 
77 was executed in 33.1 ms 
78 was executed in 33.17 ms 
79 was executed in 41.53 ms 
80 was executed in 33.18 ms 
81 was executed in 41.49 ms 
82 was executed in 33.15 ms 
83 was executed in 33.22 ms 
84 was executed in 41.52 ms 
85 was executed in 33.19 ms 
86 was executed in 33.19 ms 
87 was executed in 66.5 ms 
88 was executed in 33.16 ms 
89 was executed in 75.42 ms 
90 was executed in 57.55 ms 
91 was executed in 33.27 ms 
92 was executed in 41.43 ms 
93 was executed in 33.14 ms 
94 was executed in 33.19 ms 
95 was executed in 41.54 ms 
96 was executed in 33.15 ms 
97 was executed in 33.24 ms 
98 was executed in 41.45 ms 
99 was executed in 33.23 ms 
100 was executed in 33.15 ms 
101 was executed in 41.55 ms 
102 was executed in 33.22 ms 
103 was executed in 274.54 ms 
104 was executed in 291.28 ms 
105 was executed in 149.72 ms 
106 was executed in 91.42 ms 
107 was executed in 274.68 ms 
108 was executed in 278.38 ms 
109 was executed in 154.23 ms 
110 was executed in 432.75 ms 
111 was executed in 424.47 ms 
112 was executed in 309.66 ms 
113 was executed in 1101.32 ms 
114 was executed in 327.63 ms 
115 was executed in 116.23 ms 
116 was executed in 34.24 ms 
117 was executed in 33.18 ms 
118 was executed in 65.39 ms 
119 was executed in 34.36 ms 
120 was executed in 30.48 ms 
121 was executed in 35.85 ms 
122 was executed in 33.18 ms 
123 was executed in 41.54 ms 
124 was executed in 33.13 ms 
125 was executed in 33.23 ms 
126 was executed in 41.49 ms 
127 was executed in 83.13 ms 
128 was executed in 33.13 ms 
129 was executed in 41.58 ms 
130 was executed in 33.15 ms 
131 was executed in 33.17 ms 
132 was executed in 41.5 ms 
133 was executed in 33.18 ms 
134 was executed in 41.54 ms 
135 was executed in 33.13 ms 
136 was executed in 33.19 ms 
137 was executed in 41.55 ms 
138 was executed in 33.14 ms 
139 was executed in 33.21 ms 
140 was executed in 41.5 ms 
141 was executed in 33.22 ms 
142 was executed in 33.17 ms 
143 was executed in 41.51 ms 
144 was executed in 33.13 ms 
145 was executed in 33.22 ms 
146 was executed in 41.51 ms 
147 was executed in 75.34 ms 
148 was executed in 39.76 ms 
149 was executed in 34.38 ms  
150 was executed in 33.12 ms 

This script was executed in 13.45 seconds
这是配置文件:

# The MySQL server
[wampmysqld]
port        = 3306
socket      = /tmp/mysql.sock
query_cache_size=32M
# key_buffer = 16M
max_allowed_packet = 1M
table_cache = 64
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
编辑:解决方案

最后,将ENGINE=InnoDB更改为MyISAM后,查询在不到3秒内执行了20000行


谢谢@JOHN的帮助!PDO帮了很多忙

您的问题可能是由于向数据库发出了>20000+1个查询而导致的


如果可能,尝试概括update语句,一次覆盖多行。因此,您可以减少查询的总数。

请注意,要进行一些优化:

使用
准备好的语句(例如,或实现)如果可能的话,总是使用,它们效率更高,可以避免sql注入等。此外,考虑使用<代码> mySqLI:/COD>扩展,<代码> mysql 被认为过时了。
还有一件事需要考虑:如何获得这些
$Amaster
Amain
值?它们是存储在脚本中还是分别为每行检索

更详细地说:

每次使用
mysql\u query
执行查询时,数据库都会执行请求规划。对于影响少量行的查询,与执行本身相比,计划可能需要花费很多时间(这里没有任何统计数据,但我相信在复杂查询和短输出的情况下,这可能是数量级的倍)。因此,如果您要执行大量类似的查询,这是非常低效的,因为每个查询都要执行计划

为了避免这种情况,您应该使用准备好的语句。这背后的想法是创建一个命名对象,该对象可以缓存查询的计划并跳过计划过程,直接跳到执行步骤

在实践中,我遇到过这样一种情况:与原始sql查询(约100000条记录)相比,使用准备好的语句将执行速度提高了近百倍

DBMS中应该支持预处理语句,但据我所知,它们是

一些样品
首先,您应该在每个表中使用主键

如果您将master.DialCode更改为非空主键,它将有很大帮助

slave.DialCode也是唯一的吗?如果没有,为什么在查询中有order by和limit

当您有主键时,您可以尝试捆绑更多记录(比如100条或更多),并使用replace-into立即更新它们

REPLACE INTO slave (DialCode, NewAreaName) Values
('code1','name1'),
('code2','name2'),
('code3','name3');

首先,请分享您的更新查询,这将帮助我们指导您优化表中是否有索引,如果有,请提供这些索引的详细信息。如果您的表上没有任何索引,那就是开始的地方。@Dan Dialcode应该是索引,我在phpmyadmin中单击了索引,我得到一行:
ALTERTABLE master ADDINDEX Dialcode
,但它被视为键,这是同一件事吗?我在一个只有150行的新表中尝试了,但是没有帮助。我用新代码和新查询编辑了我的问题,但是仍然太慢。你尝试过禁用拨号代码的索引吗?这可能会减慢查询速度。我只是尝试将其从主控和从控中删除,但对于这样一个简单的查询,它提供了相同的时间(17秒)。请一步一步地为整个脚本计时,或者我认为您正在尝试修复未损坏的内容:)@JOHN我已经为所有代码计时,这样我发现这个查询是主要问题。我在第一条消息中提供了要测试的代码和sql表。你能检查一下有没有什么问题吗?你得到同样的结果吗?非常感谢你@我也需要数据。你能用一些记录对你的表进行SQL转储(我想150个就足够了)并把它发布到服务器上吗?
$pdo = new PDO(/*your database connection properties here*/);
$update_stmt = $pdo->prepare("UPDATE slave SET NewAreaName = ? WHERE Dialcode = ? ORDER BY Dialcode ASC LIMIT 1");

/*Iterate over $Rmaster  as you do it now{*/
    $update_stmt->execute(array($Amaster['AreaName'], $Amain['AreaCode']));
/*}*/
REPLACE INTO slave (DialCode, NewAreaName) Values
('code1','name1'),
('code2','name2'),
('code3','name3');