这是我到目前为止所读到的PDO::ATTR_EMULATE_PREPARES:
我不知道这些陈述是多么真实.选择MySQL接口时我最担心的是阻止SQL注入.第二个问题是表现.
我的应用程序目前使用过程MySQLi(没有预处理语句),并且使用了很多查询缓存.它很少会在单个请求中重复使用预准备语句.我开始转向PDO以获取已准备好的语句的命名参数和安全性.
我正在使用MySQL 5.1.61和PHP 5.3.2
我应该PDO::ATTR_EMULATE_PREPARES启用还是不启用?有没有办法既具有查询缓存的性能又具有预准备语句的安全性?
我们在其中一个网站上有一个搜索引擎,速度非常慢.我打开了慢查询日志并记录了所有超过10秒的查询.仅记录来自此搜索引擎的查询.以下是日志的一个示例:
# Time: 120801 9:21:42
# User@Host: ********** @ localhost []
# Query_time: 22.156250 Lock_time: 0.000000 Rows_sent: 33 Rows_examined: 3385401
SET timestamp=1343805702;
SELECT *, IF(InSection OR InBranche, 1, 0) AS SorteerKolom FROM(SELECT DISTINCT Plant, Email, Nicename, Displayname, JobTitle, Department, Initials, Lastname, LastnameForSort,
search_people.ForeignId, IsVennoot,
(Zoekwoorden LIKE '%statutair%') AS SearchTerm,
(Displayname LIKE '%statutair%') AS ByName,
0 AS InSection, 0 AS InBranche, 1 AS ShowAll,
(SELECT COUNT(*) FROM search_hasarticles WHERE UserId = search_people.ForeignId) > 0 AS HasWritten
FROM search_people
LEFT JOIN search_people_branches …Run Code Online (Sandbox Code Playgroud) 据我所知,MySQL 5.1支持服务器端预处理语句.因此,以下代码应该准备一次语句,并执行10次:
Connection conn = ds.getConnection();
PreparedStatement stmt = conn.prepareStatement("SELECT COUNT(*) FROM users WHERE user_id=?");
for (int i=0; i<10; i++)
{
stmt.setString(1, "FOO"+i);
ResultSet res = stmt.executeQuery();
res.close();
}
stmt.close();
conn.close();
Run Code Online (Sandbox Code Playgroud)
我在mysqld日志中看到的是直接执行的查询:
SELECT @@session.tx_isolation
SELECT USER()
SELECT COUNT(*) FROM users WHERE user_id='FOO0'
SELECT COUNT(*) FROM users WHERE user_id='FOO1'
SELECT COUNT(*) FROM users WHERE user_id='FOO2'
...
Run Code Online (Sandbox Code Playgroud)
我也在协议日志中看到了每次都发送的查询(使用tcpdump).
使用Connector/J 5.1.12和MySQL 5.1.44.JDBC URL中没有有趣的JDBC选项.直接去驾驶员进行这项测试,没有游泳池.
为什么不准备这些陈述?