PHP+;MySQL在一台机器上运行太慢
我已经尝试了从类似问题中找到的所有建议,但似乎没有一个有用 我正在运行一个PHP脚本,将一些数据添加到数据库中——大约只有1K行。以下是我使用的完整代码:PHP+;MySQL在一台机器上运行太慢,php,mysql,Php,Mysql,我已经尝试了从类似问题中找到的所有建议,但似乎没有一个有用 我正在运行一个PHP脚本,将一些数据添加到数据库中——大约只有1K行。以下是我使用的完整代码: <?php header('Content-Type: text/plain'); $t_start = microtime(true); require('../php/connect.php'); $data = json_decode(file_get_contents('base/en/stringlist.js')); for
<?php
header('Content-Type: text/plain');
$t_start = microtime(true);
require('../php/connect.php');
$data = json_decode(file_get_contents('base/en/stringlist.js'));
foreach ($data as $cat => $values) {
$category = mysql_real_escape_string($cat);
foreach ($values as $key => $info) {
$name = mysql_real_escape_string($key);
$text = mysql_real_escape_string($info->text);
$tip = mysql_real_escape_string(isset($info->tip) ? $info->tip : '');
$query = "INSERT INTO locale_strings (name,text,tip,category) VALUES ('$name','$text','$tip','$category')";
if (!mysql_query($query)) {
echo mysql_error() . "\n";
}
}
}
echo 'Time: ' . round(microtime(true) - $t_start, 4) . ' seconds.';
?>
InnoDB存储引擎是兼容的。每个查询都以自动提交模式运行,并将使用磁盘的输入输出操作,这相当昂贵。这意味着每个查询都会强制硬盘(HDD)写入记录(而不是让操作系统安排它)。你的硬盘,如果是机械的,每秒大约有300个I/O。这意味着,对于大约900-1000条记录,记录下来可能需要2-3秒 相反,正如我提到的,使用MyISAM存储引擎可以让操作系统安排写操作。记录不会立即写入磁盘;在保存到磁盘之前,它们在内存中。虽然这意味着MyISAM的速度更快,但权衡的是数据丢失的风险(如果系统在缓冲区中存在尚未写入磁盘的数据时崩溃或断电) 为了优化这一点,通常的方法是将多个插入封装到单个事务中。一种方法是使用、准备语句、启动事务并在完成1000次插入后提交。 这允许硬盘在一次操作中写入大量数据 使用PDO重写的代码的流程与此类似(注意-未测试,不复制粘贴,仅供参考):
InnoDB存储引擎是兼容的。每个查询都以自动提交模式运行,并将使用磁盘的输入输出操作,这相当昂贵。这意味着每个查询都会强制硬盘(HDD)写入记录(而不是让操作系统安排它)。你的硬盘,如果是机械的,每秒大约有300个I/O。这意味着,对于大约900-1000条记录,记录下来可能需要2-3秒 相反,正如我提到的,使用MyISAM存储引擎可以让操作系统安排写操作。记录不会立即写入磁盘;在保存到磁盘之前,它们在内存中。虽然这意味着MyISAM的速度更快,但权衡的是数据丢失的风险(如果系统在缓冲区中存在尚未写入磁盘的数据时崩溃或断电) 为了优化这一点,通常的方法是将多个插入封装到单个事务中。一种方法是使用、准备语句、启动事务并在完成1000次插入后提交。 这允许硬盘在一次操作中写入大量数据 使用PDO重写的代码的流程与此类似(注意-未测试,不复制粘贴,仅供参考):
InnoDB存储引擎是兼容的。每个查询都以自动提交模式运行,并将使用磁盘的输入输出操作,这相当昂贵。这意味着每个查询都会强制硬盘(HDD)写入记录(而不是让操作系统安排它)。你的硬盘,如果是机械的,每秒大约有300个I/O。这意味着,对于大约900-1000条记录,记录下来可能需要2-3秒 相反,正如我提到的,使用MyISAM存储引擎可以让操作系统安排写操作。记录不会立即写入磁盘;在保存到磁盘之前,它们在内存中。虽然这意味着MyISAM的速度更快,但权衡的是数据丢失的风险(如果系统在缓冲区中存在尚未写入磁盘的数据时崩溃或断电) 为了优化这一点,通常的方法是将多个插入封装到单个事务中。一种方法是使用、准备语句、启动事务并在完成1000次插入后提交。 这允许硬盘在一次操作中写入大量数据 使用PDO重写的代码的流程与此类似(注意-未测试,不复制粘贴,仅供参考):
InnoDB存储引擎是兼容的。每个查询都以自动提交模式运行,并将使用磁盘的输入输出操作,这相当昂贵。这意味着每个查询都会强制硬盘(HDD)写入记录(而不是让操作系统安排它)。你的硬盘,如果是机械的,每秒大约有300个I/O。这意味着,对于大约900-1000条记录,记录下来可能需要2-3秒 相反,正如我提到的,使用MyISAM存储引擎可以让操作系统安排写操作。记录不会立即写入磁盘;在保存到磁盘之前,它们在内存中。虽然这意味着MyISAM的速度更快,但权衡的是数据丢失的风险(如果系统在缓冲区中存在尚未写入磁盘的数据时崩溃或断电) 为了优化这一点,通常的方法是将多个插入封装到单个事务中。一种方法是使用、准备语句、启动事务并在完成1000次插入后提交。 这允许硬盘在一次操作中写入大量数据 使用PDO重写的代码的流程与此类似(注意-未测试,不复制粘贴,仅供参考):
如果sql查询运行缓慢,原因很多。首先显然是硬件限制。即使在那之后,你也需要精心设计适当的查询,同时优化数据库体系结构以加快查询速度。这似乎是第三台机器的硬件或其他限制。是的,我知道这个问题太具体了,我基本上是问是否有任何已知的特定硬件问题可能导致这种情况。您使用的是InnoDB。InnoDB是一个符合ACID标准的引擎。每个查询都以自动提交模式运行。这意味着每个查询都会强制HDD写下一条记录(而不是让操作系统安排它)。你的硬盘,如果是机械的,每秒大约有300个I/O。这意味着,对于大约900-1000条记录,记录下来可能需要2-3秒。有很多方法可以优化这一点。一种方法是使用PDO,pr
CREATE TABLE IF NOT EXISTS `locale_strings` (
`id` int(11) NOT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`category` varchar(255) NOT NULL,
`text` text NOT NULL,
`locked` int(11) NOT NULL DEFAULT '0',
`tip` text NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=4833 DEFAULT CHARSET=utf8;
ALTER TABLE `locale_strings`
ADD PRIMARY KEY (`id`);
ALTER TABLE `locale_strings`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=4833;
// connect.php - note that the code around PDO should go in the file connect.php as per example
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
try
{
$pdo = new PDO($dsn, $user, $password, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
echo 'Connection failed: ' . $e->getMessage();
}
//===================================================================
// The rest of the code
//===================================================================
// Decode JSON
$data = json_decode(file_get_contents('base/en/stringlist.js'));
// Check if there were any errors decoding JSON
if(empty($data))
{
echo "Something went wrong, error: " . json_last_error_msg();
exit;
}
try
{
// Prepare the statement - it's prepared once, used multiple times
$stmt = $pdo->prepare("INSERT INTO locale_strings (name, text, tip, category) VALUES (:name, :text, :tip, :category)");
// Start the transaction
$pdo->beginTransaction();
// Loop through the data, bind parameters, execute and when done - commit
foreach ($data as $cat => $values)
{
foreach ($values as $key => $info)
{
$stmt->bindValue(':name', $key, PDO::PARAM_STR);
$stmt->bindValue(':text', $info->text, PDO::PARAM_STR);
$stmt->bindValue(':tip', isset($info->tip) ? $info->tip : '', PDO::PARAM_STR);
$stmt->bindValue(':category', $cat, PDO::PARAM_STR);
$stmt->execute();
}
}
// And finally, tell the HDD to write down the info.
// Note - for this example, we issued all the contents in a single commit.
// That might not be the sweet spot so you can optimize later on with checking
// how many records are optimal go do down to the disk in a single I/O
$pdo->commit();
}
catch(PDOException $e)
{
if($pdo->inTransaction())
{
$pdo->rollBack();
}
// I assume you know how to handle exceptions, messages, trace etc.
}