如何加快PDO查询速度

时间:2017-12-12 18:38:48

标签: php mysql performance pdo

我有产品数据库表(tabl_products)超过 55百万行(产品)和iam使用 PDO查询来显示tabl_products表中的每个产品,所以这里是我的查询表structre并选择查询..

id | pr_name | pr_description | pr_qntty | pr_price


$pr_id = (int)$_GET['id'];
$select_pr = $con->prepare("SELECT pr_name, pr_description, pr_price FROM tabl_products WHERE id=:pr_id");
$select_pr->bindParam(":pr_id", $pr_id);
$select_pr->execute();
if(!($select_pr->rowCount()))
{
   include '404.php'; exit();
}
$fetch_pr = $select_pr->fetch(PDO::FETCH_ASSOC);

echo $pr_name = $fetch_pr['pr_name'].'<br/>';
echo $pr_description = $pr_description['pr_description'].'<br/>';
echo $pr_price = $fetch_all['pr_price'];

以上查询需要2到3分钟才能显示单个产品信息。

那么如何在5到10秒内显示单个产品信息?

(来自评论)

CREATE TABLE IF NOT EXISTS tabl_products (
    id int(11) NOT NULL AUTO_INCREMENT, 
    pr_name varchar(255) NOT NULL, 
    pr_description varchar(255) NOT NULL, 
    pr_qntty varchar(255) NOT NULL, 
    pr_price varchar(255) NOT NULL, 
    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

2 个答案:

答案 0 :(得分:1)

我使用MySQL 5.7.20重新创建了类似的数据库,用虚拟数据填充了大约55000000行,并且查询如下:

org.openqa.selenium.support.ui.UnexpectedTagNameException: Element should have been "select" but was "mat-select" Build info: version: '3.8.1', revision: '6e95a6684b', time: '2017-12-01T19:05:14.666Z' System info: host: '', ip: '127.0.0.1', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0_131' Driver info: driver.version: unknown at org.openqa.selenium.support.ui.Select.<init>(Select.java:47) at com.morrisons.automation.pageobjects.sma.SchedulePageObject.clickandselectstoregroup(SchedulePageObject.java:225) at com.morrisons.automation.stepdefs.sma.NewScheduleStepDef.i_select_storegroup_dropdown_and_select_dropdown_value(NewScheduleStepDef.java:98) at ?.And I select storegroup dropdown and select dropdown value(C:/AutomationNeon1/atom/src/main/features/smascheduler/new-schedule.feature:22)

在我的(不错的)PC上很快返回结果(在MYSQL Workbench中显示0.000秒)。

我可以给你一些可以让你发现问题的想法。首先,您的代码中存在一些错误。

SELECT * FROM stackoverflow_test.tabl_products WHERE id=12345678;

echo $pr_name = $fetch_pr['pr_name'].'<br/>'; echo $pr_description = $pr_description['pr_description'].'<br/>'; echo $pr_price = $fetch_all['pr_price']; 应替换为$pr_description

$fetch_pr应替换为$fetch_all

也许你的php文件中有其他东西会让执行变得如此之慢。尝试执行最小文件,或使用MySQL Workbench(或类似工具)来确保它不是http服务器或php的问题(可能查询运行速度很快,但是提取速度很慢,或者还有其他问题?)。

特别是对于这么大的数据库,您需要确保使用索引。在MySQL中,您可以通过在查询前添加$fetch_prhttps://dev.mysql.com/doc/refman/5.7/en/explain-output.html)来完成此操作,即:

EXPLAIN

然后分析字段 possible_keys ,其中应包含索引名称(PRIMARY)。如果MySQL没有使用索引,那么在查询中添加EXPLAIN SELECT * FROM stackoverflow_test.tabl_products WHERE id=12345678;https://dev.mysql.com/doc/refman/5.7/en/index-hints.html)语句会有所帮助,但您应该调查默认情况下不使用它的原因。

仅当我添加USE INDEX (`PRIMARY`)以检查没有索引的查询执行时间时,查询运行大约30秒而不是几分之一。

这也是服务器过载或不够强大的可能性,但是对于索引,您的查询应该非常快。

用户Your Common Sense建议即使使用了索引,它也可能太大而无法放入内存,因此从磁盘中读取速度很慢。您可能需要检查索引的大小并将其与可用内存进行比较,并(如果需要)相应地调整MySQL内存设置。

答案 1 :(得分:-2)

由于您的id是唯一的(主键),您可以添加LIMIT 1。因为,即使您的产品被发现一次,PDO也会继续查看具有该特定ID的其他产品。

所以你的查询变为:

SELECT pr_name, pr_description, pr_price FROM tabl_products WHERE id=:pr_id LIMIT 1

尝试告诉我们需要多长时间:)

PS:它由Doctrine ORM使用,例如: