PHP/MySQL 准备好的语句 - 一个用户可以从另一用户准备好的查询中受益吗?

发布于 2024-10-06 16:38:00 字数 613 浏览 3 评论 0原文

是否有任何类型的服务器端优化(例如在 MySQL 数据库中)允许一个用户准备的查询从另一个用户之前准备的查询中受益? (这里的重点是用户之间可能的性能改进,每个查询在单独的 php 脚本期间运行。)

示例:

查询用户 1:SELECT * FROM SomeTable WHERE item1 = ?和项目 2 = ?

第 1 项 = x item 2 = y

用户 2 的查询: SELECT * FROM SomeTable WHERE item1 = ?和项目 2 = ? (与上面相同的查询)

项目 1 = y item 2 = z

如果这个相同的准备好的查询(尽管每次使用不同的参数)只会为每个不同的用户执行一次,那么使用准备好的查询是否有任何潜在的性能提升?

或者对第 1 项和第 2 项使用 real_escape_string 函数,然后将它们直接放入查询中会更好吗?这将避免两次访问数据库,一次检查准备好的查询的有效性,另一次实际执行查询。

我并不那么担心 SQL 注入,因为通过适当的转义,任何一种方法都应该同样安全。 (对吗?)老实说,我只是想知道如果我不在同一个 php 脚本中多次迭代执行相同的准备好的查询,是否值得使用准备好的语句。

谢谢!

Is there any kind of server-side optimization (like in a MySQL database) that allows one user's prepared query to benefit from another user's previously prepared query? (The emphasis here is on possible performance improvements BETWEEN users, each query running during a separate php script.)

Example:

Query for user 1: SELECT * FROM SomeTable WHERE item1 = ? and item2 = ?

item 1 = x
item 2 = y

Query for user 2: SELECT * FROM SomeTable WHERE item1 = ? and item2 = ? (same query as above)

item 1 = y
item 2 = z

If this identical prepared query (though with different parameters each time) will only be executed once for each of these different users, is there any potential performance gain from using a prepared query?

Or would it just be better to use the real_escape_string function on items 1 and 2, and just put them right into the query. This would avoid making two trips to the db, one to check the validity of the prepared query, and the other to actually execute the query.

I'm not all that worried about SQL injection, since with proper escaping, either method should be just as safe. (Right?) I'm honestly just wondering if it's worth using prepared statements if I'm not iterating through the execution of the same prepared query multiple times within the same php script.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

毁虫ゝ 2024-10-13 16:38:00

这取决于您使用的 MySQL 版本。请参阅此页面: http://dev.mysql.com /doc/refman/5.1/en/query-cache-operation.html
如果你使用MySQL 5.1.17之前的版本,prepared statements不会被缓存,并且使用MySQL查询缓存比使用prepared statements给出更好的结果,所以你最好担心你是否在使用这个缓存是否有优化的方式。
否则,我认为你的问题的答案是肯定的,因为不是这样做两次:

  1. 将请求发送到服务器,
  2. 编译请求
  3. 执行计划,
  4. 执行请求,
  5. 将结果发送回来,

你会这样做:

准备:

  1. 将请求发送到服务器,
  2. 编译请求
  3. 执行计划
  4. 将编译后的请求存储在内存中
  5. 返回一个请求标识符

EXECUTE 并带有第一组参数:

  1. 请求使用标识符执行
  2. 执行
  3. 返回结果

EXECUTE 另一组参数:
1. 使用标识符请求执行
2.执行
3. 返回结果

(所有这些均翻译自关于准备好的语句的法语课程< /a>)
正如您所看到的,如果满足以下条件,您将获得真正的性能提升:

  • 您多次执行此请求
  • 请求很复杂并且需要时间来编译
  • 使用查询缓存

It depends on which version of MySQL you are using. See this page : http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html
If you are using MySQL before version 5.1.17, prepared statements won't be cached, and the use of MySQL query cache gives better results than the use of prepared statements, so you'd better worry about whether you are using this cache in an optimized way or not.
Otherwise, I think the answer to your question is yes, because instead of doing this twice:

  1. send the request to the server
  2. compile the request
  3. execution plan
  4. execute request
  5. send result back

you would do this:

PREPARE :

  1. send the request to the server
  2. compile the request
  3. execution plan
  4. store the compiled request in memory
  5. return a request identifier

EXECUTE with first series of parameters:

  1. ask for execution with the identifier
  2. execute
  3. return result

EXECUTE another series of parameters:
1. ask for execution with the identifier
2. execute
3. return result

(all this was translated from this french course on prepared statements)
As you see, you'll have a real performance gain if:

  • you execute this request a lot
  • the request is complex and takes time to compile
  • the query cache is used
鸠书 2024-10-13 16:38:00

您始终可以调用存储过程 - 这只是一次调用:)

drop procedure if exists get_user;
delimiter #

create procedure get_user
(
in p_user_id int unsigned
)
proc_main:begin
    select u.* from users u where u.user_id = p_user_id;
end proc_main#

delimiter ;

call get_user(1);
call get_user(3);
call get_user(6);

you could always call a stored procedure - it's just a single call :)

drop procedure if exists get_user;
delimiter #

create procedure get_user
(
in p_user_id int unsigned
)
proc_main:begin
    select u.* from users u where u.user_id = p_user_id;
end proc_main#

delimiter ;

call get_user(1);
call get_user(3);
call get_user(6);
GRAY°灰色天空 2024-10-13 16:38:00

这里的问题是您的两个实例无法共享任何代码(无需投入大量精力)。准备查询两次应该可以忽略不计。如果确实存在性能瓶颈,则问题可能是其他原因。

The problem here is that your two instances cannot share any code (without putting a lot of effort into it). Preparing the query twice should be negligible. If there are actual performance bottlenecks, the problem is probably something else.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文