我有一个特殊的查询,由于某种原因,在使用PDO绑定时(通过this
)似乎有可怕的性能。我似乎对其他查询没有这个问题,所以我不确定它是否通常 这个查询,或者是否存在更大的基础PDO绑定的问题。
基本上,当我在没有绑定的情况下运行语句时(通过手动将原始绑定自身注入查询字符串[我明白这是不安全的并且可能导致SQL注入暴露]),语句运行大约100ms到200ms,对我们的申请是合理的。大多数查询通常具有带绑定的速度,但无论出于何种原因,这个都没有。
当我通过框架自然地运行语句时,绑定将传递给PDO实例。以这种方式运行查询会导致它花费40,000毫秒(40秒),方式高于预期。
我已经尝试了我能想到的每一个组合来找到问题的根本原因,并且我确定它是PDO绑定。我甚至在没有PDO的情况下尝试了相同的查询,我也没有遇到同样的问题。在RDS中运行原始查询只需要80ms(由于开销较少,速度更快)。
我们还将PHP,Apache和我们的MSSQL / ODBC驱动程序更新到最新版本,但这些版本并没有改变性能。
我不知道为什么PDO绑定这么慢,而且我不知道我们对这种明显缓慢的曝光是什么(因为这个问题导致其他查询在我们的应用程序中可能会很慢)。我知道这个查询是我们现在唯一已知的问题实例。
查询本身:
$statement->execute($bindings)
绑定(替换查询中的?):
SELECT
top 10 [cars].[id],
[cars].[sponsor_id]
FROM [cars]
INNER JOIN [drivers_cars]
ON [cars].[id] = [drivers_cars].[car_id]
AND [drivers_cars].[driver_type_id] = ? -- 1
INNER JOIN [drivers]
ON [drivers_cars].[driver_id] = [drivers].[id]
AND [drivers].[deleted_at] IS NULL
WHERE [cars].[deleted_at] IS NULL
AND (
(
SELECT COUNT(*)
FROM [drivers]
INNER JOIN [drivers_cars]
ON [drivers].[id] = [drivers_cars].[driver_id]
WHERE [drivers_cars].[car_id] = [cars].[id]
AND (
(
SELECT COUNT(*)
FROM [drivers_sponsors]
WHERE [drivers_sponsors].[driver_id] = [drivers].[id]
AND [drivers_sponsors].[driver_client_id] LIKE '469%'
) >= ? -- 1
OR [drivers].[student_id] LIKE ? -- '469%'
OR (
SELECT COUNT(*)
FROM [drivers_contacts]
WHERE [drivers_contacts].[driver_id] = [drivers].[id]
AND [contact_type] IN (?, ?, ?, ?, ?, ?) -- (1, 2, 3, 4, 5, 6)
AND [phone_number] LIKE ? -- '469%'
AND [drivers_contacts].[deleted_at] IS NULL
) >= 1
)
AND [drivers].[deleted_at] IS NULL
AND [drivers_cars].[deleted_at] IS NULL
) >= 1
OR [cars].[sponsor_car_id] LIKE ? -- '469%'
)
ORDER BY [drivers].[last_name] ASC
PDO实例:
"bindings" => [
0 => 1,
1 => 1,
2 => "469%",
3 => 1,
4 => 2,
5 => 3,
6 => 4,
7 => 5,
8 => 6,
9 => "469%",
10 => "469%",
]
任何反馈都将不胜感激。