(PHP MYSQLI)当我使用SELECT OR时,奇怪的'没有使用索引'错误

时间:2015-08-11 09:40:45

标签: php mysql mysqli

当我使用mysqli prepared statement进行查询时,我收到了这个错误:

No index used in query/prepared statement SELECT * FROM `signin_log` WHERE `account` = ? OR `account` = ? ORDER BY `log_id` DESC

代码是:

$sql = 'SELECT * FROM `signin_log` WHERE `account` = ? OR `account` = ?  ORDER BY `log_id` DESC';
$params = array($username, $email);                                                                                                      
$result = (new AccountDAO())->executeQuery($sql, $params, 'ss'); 

这是表格def:

create table `signin_log`(
  `log_id` int AUTO_INCREMENT,
  primary key(`log_id`),
  `account` varchar(45) NOT NULL,
  index(`account`),
  `accepted` char NOT NULL,
  `time` int NOT NULL,
  `ip` long NOT NULL
)ENGINE = MyISAM DEFAULT CHARSET = utf8;

我知道这个错误意味着查询不包含db必须扫描整个表的索引,但我想我确实使用了索引account和pk log_id。 / p>

混乱。

我想知道'OR'是否发生了这个错误 - 如果你使用OR,Mysql不会使用索引,但我认为这没有意义。 等待你的帮助,谢谢!

**Solved**

我从其他页面找到了答案(My simple MySql query doesn't use indexWHAT TO DO WHEN MYSQL DOESN’T USE AN INDEX…(有点旧)。

我的查询没有任何问题,也没有使用Mysql DBMS。这个错误来自php。

这是我得到的(可能来自手册,不确定,页面是404)

  

如果MySQL可以计算它可能会被使用,则不使用索引   扫描整个表格的速度更快。例如,如果key_part1是均匀的   分布在1到100之间,使用索引并不好   以下查询:

     

SELECT * FROM table_name其中key_part1> 1和key_part1< 90

事实上,我在该表中的记录很少。当我试图扩大数量(约30,000)时,一切都干净了。

所以,为了让PHP开心,我添加了这一行:

mysqli_report(MYSQLI_REPORT_ERROR|MYSQLI_REPORT_STRICT);
谢谢大家。

2 个答案:

答案 0 :(得分:1)

对于小型表或测试环境,如果已定义,则mysql不能使用索引。无论哪种方式,您都必须通过运行EXPLAIN查询来询问数据库的答案。没有人能告诉你你的mysql是否使用了索引。

但是,您可以关闭这些警告。而不是

mysqli_report(MYSQLI_REPORT_STRICT);

制作

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

"键:空"是一个有用的信息,意味着没有使用密钥。由于我上面解释的原因。您不应该更改查询,只需在表格中获取更多数据。

display_errors=E_ALL必须在所有环境中保持不变。

答案 1 :(得分:-1)

缺少的索引通知是一个相对较低的严重性警告。

致命错误在您的PHP代码中,因为以下三个条件:

  • mysqli报告了许多警告,即使是相对无害的条件。
  • 由于mysqli_report(MYSQLI_REPORT_ALL)行导致所有错误和警告,您正在抛出mysqli_sql_exception。
  • 您的PHP代码没有捕获该异常(即它不在具有适当catch(){}块的try {}块中,并且未捕获的异常是致命的。你不能对第一个做太多,如另一个答案所述。因此,您可以通过将mysqli_report(...)设置更改为MYSQLI_REPORT_STRICT或MYSQLI_REPORT_OFF,或者实际上除MYSQLI_REPORT_ALL之外的其他任何内容来修复它。

另一种解决方法是使用:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

对于最佳做法,并与此相结合,您应该在代码中正确使用try {}和catch(){}来正确修复它。