只有在绑定参数时,我才会遇到特定查询的奇怪性能问题。
这是我的代码:
$statement = $connection->prepare('SELECT count(item_id) AS count FROM MyView WHERE active = 1 AND context_id = 5 AND snapshot_id = 24');
$time_start = microtime_float();
$statement->execute();
$time_end = microtime_float();
$time1 = round($time_end - $time_start, 4);
$result = $statement->fetch()['count'];
$statement = $connection->prepare('SELECT count(item_id) AS count FROM MyView WHERE active = :filter_active AND context_id = :filter_context_id AND snapshot_id = :filter_snapshot_id');
$statement->bindValue('filter_active', 1, 2);
$statement->bindValue('filter_context_id', 5, 2);
$statement->bindValue('filter_snapshot_id', 24, 2);
$time_start = microtime_float();
$statement->execute();
$time_end = microtime_float();
$time2 = round($time_end - $time_start, 4);
$result = $statement->fetch()['count'];
enter code here
时间结果:
time1 = 0.79 sec
time2 = 31.50 sec
有人可以解释一下为什么我们会有这么大的性能差异吗?
由于
EDIT&解: 参数类型错误。我应该使用PDO :: PARAM_INT。 请注意,如果我没有指定param类型,则性能非常差。
答案 0 :(得分:0)
哦,问题和的问题有多少问题!
SHOW CREATE TABLE
- 我们需要查看数据类型,索引和引擎(至少)。(active, context_id, snapshot_id)
上建立索引。count(item_id)
,而是count(*)
。前者是您需要测试item_id
而不是NULL
。WHERE int_col = 123
和WHERE int_col = "123"
的效果几乎完全相同,效果相同。一个不好的组合是WHERE char_col = 123
- 在这种情况下,它会在比较之前将每个char_col
转换为数字;这使得索引无用。0.0005 sec
很可能是假的。您可能已启用查询缓存 - 这种情况很少发生在最近运行查询,缓存在QC中,然后再次运行时。它不是重新执行查询,而是简单地从QC中提取结果集。SELECT SQL_NO_CACHE ...
来避免质量控制。然后运行两次(并采取第二个时间)以避免I / O缓存。