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


(PHP MYSQLI) Strange 'No index used' error when I USE SELECT OR

当我使用mysqli准备语句进行查询时,我得到了这个错误:

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

让人困惑。

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

**Solved**

我从其他页面找到了答案(我的简单MySql查询不使用索引,当MySql不使用索引时该怎么办…(有点旧))。

我的查询没有错,Mysql DBMS也没有错。这个错误来自php。

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

如果MySQL可以计算出它可能会使用索引,则不使用索引更快地扫描整个表。例如如果key_part1是均匀的分布在1到100之间,在以下查询:SELECT * FROM table_name where key_part1> 1 and key_part1 <90

事实上,我在那个表中几乎没有记录。当我尝试扩展num(约30,000)时,一切都干净了。

所以,为了让PHP高兴,我添加了这行:
mysqli_report(MYSQLI_REPORT_ERROR|MYSQLI_REPORT_STRICT);

谢谢大家。

对于小表或测试环境,即使已经定义了索引,mysql也可以不使用索引。无论哪种方式,您都必须通过运行EXPLAIN查询向数据库询问答案。没有人知道你的mysql是否使用了索引。

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

mysqli_report(MYSQLI_REPORT_STRICT);

make it

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

"key:null"是一个有用的信息,表示没有键被使用。原因我在上面解释过。你不应该改变你的查询,而只是在你的表中获得更多的数据。

display_errors=E_ALL必须在所有环境中保持相同。

缺失索引通知是一个相对较低级别的警告。

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

  • mysqli报告很多警告,即使是相对无害的情况。
  • 你抛出mysqli_sql_exception所有错误和警告由于mysqli_report(MYSQLI_REPORT_ALL)行。
  • 你的PHP代码没有捕捉到异常(即它不是在try{}块与适当的catch(){}块),未捕获的异常是致命的。正如另一个答案中提到的,你对第一个问题做不了什么。所以,你可以通过改变mysqli_report(…)设置为MYSQLI_REPORT_STRICT或MYSQLI_REPORT_OFF,或者除了MYSQLI_REPORT_ALL之外的任何东西来修复它。

另一种解决方法是使用:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

对于最佳实践,并结合这一点,您应该通过在代码中适当地使用try{}和catch(){}来正确地修复它。

the "在查询/预处理语句中没有使用索引"不是关于PHP,而是关于你的设计表:只需添加一个索引到你的表。

真正最好的是在DEVELOP中打开错误/警告:

mysqli_report(MYSQLI_REPORT_ALL);

但是在生产环境中关闭警告:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);