致命错误:未捕获的异常 'mysqli_sql_exception' 带有消息 'No index used in query/prepared statement'
Posted
技术标签:
【中文标题】致命错误:未捕获的异常 \'mysqli_sql_exception\' 带有消息 \'No index used in query/prepared statement\'【英文标题】:Fatal error: Uncaught exception 'mysqli_sql_exception' with message 'No index used in query/prepared statement'致命错误:未捕获的异常 'mysqli_sql_exception' 带有消息 'No index used in query/prepared statement' 【发布时间】:2011-07-31 14:30:07 【问题描述】:当我运行以下代码时,我收到错误提示
致命错误:未捕获的异常 带有消息的“mysqli_sql_exception” '查询/准备中没有使用索引 声明'
$mysql = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or die('There was a problem connecting to the database');
if (mysqli_connect_errno())
printf("DB error: %s", mysqli_connect_error());
exit();
$get_emp_list = $mysql->prepare("SELECT id, name FROM calc");
if(!$get_emp_list)
echo "prepare failed\n";
echo "error: ", $mysql->error, "\n";
return;
$get_emp_list->execute();
$get_emp_list->bind_result($id, $emp_list);
这是可行的模式--
--
-- Table structure for table `calc`
--
CREATE TABLE IF NOT EXISTS `calc` (
`id` int(12) NOT NULL,
`yr` year(4) NOT NULL,
`mnth` varchar(12) NOT NULL,
`name` varchar(256) NOT NULL,
`paidleave` int(12) NOT NULL,
`balanceleave` int(12) NOT NULL,
`unpaidleave` int(12) NOT NULL,
`basesalary` int(12) NOT NULL,
`deductions` int(12) NOT NULL,
`tds` int(12) NOT NULL,
`pf` int(12) NOT NULL,
`finalsalary` int(12) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
【问题讨论】:
【参考方案1】:致命错误不在 MySQL 中;缺少索引通知是一个相对低严重性的警告。
致命错误在您的 php 代码中,因为以下三个情况:
mysqli 报告了很多个警告,即使在相对无害的情况下也是如此。 由于您的mysqli_report(MYSQLI_REPORT_ALL);
行,您将抛出mysqli_sql_exception
的所有错误和警告。
您的 PHP 代码没有捕获该异常(即它不在具有适当 catch()
块的 try
块中),未捕获的异常是致命的。
正如另一个答案中提到的,你不能对第一个做太多事情。因此,您可以通过将mysqli_report(...)
设置更改为MYSQLI_REPORT_STRICT
或MYSQLI_REPORT_OFF
或MYSQLI_REPORT_ALL
以外的任何设置来修复它。
(编辑:w3d 下面的评论很好地解释了原因,并建议您可以使用mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)
作为一个不错的选择)
为了获得最佳实践,并结合这一点,您应该通过在代码中适当地使用try
和catch()
来正确修复它。
【讨论】:
它通常是低严重性但不应忽视:消息指出mysql服务器必须执行全表扫描,即必须检查每条记录是否属于结果集.在大型数据库的情况下,搜索列的附加索引可能会有所帮助。 具体来说,要删除这些特定警告,您需要从report_mode
属性中删除MYSQLI_REPORT_INDEX
标志。此标志“报告查询中是否使用了索引或错误索引”。因此,在执行查询之前使用 mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)
而不是 mysqli_report(MYSQLI_REPORT_ALL)`。【参考方案2】:
mysqli_report(MYSQLI_REPORT_ALL ^ MYSQLI_REPORT_INDEX);
关闭“在查询中未使用索引或错误索引时报告”但保持其他报告打开。
【讨论】:
【参考方案3】:看看这个错误报告:#35450
mysqli extension reports too many warnings
引用笔记中的几句话:
Mysqli 扩展抛出太多 警告。 例如,“选择 * FROM 表”导致警告: “警告:mysqli::query(): 没有索引 用于查询/准备语句 SELECT * FROM 表..."
并且,引用另一个注释,这似乎很有趣:
使用
mysqli_report()
禁用它。
【讨论】:
嗯...我不认为这是弃用的,因为我使用它很好.. mysqli_report(MYSQLI_REPORT_ALL); Deprecated 并不意味着“不起作用”,而是“不应再使用,并且可能有一天会被删除” 对,但我所拥有的不是警告,而是致命错误。我想知道致命错误。 它不应该被弃用(似乎是偶然的):bugs.php.net/bug.php?id=55329 是的,它仍然是 PHP7 中的有效命令,文档中没有弃用消息:php.net/manual/en/function.mysqli-report.php【参考方案4】:解决它的另一种方法是使 MySQL 中的表列“名称”成为索引。
ALTER TABLE `calc` ADD INDEX ( `name` ) ;
【讨论】:
如果你有一张小桌子,这还不够。在这种情况下,MySQL/MariaDB 将隐式禁用表中的索引,如果没有使用索引,则将其与 mysqli throwing 结合起来,你有一个很好的 when-stars-align 混乱 :) “适用于 prod,不适用于 staging/dev "。以上是关于致命错误:未捕获的异常 'mysqli_sql_exception' 带有消息 'No index used in query/prepared statement'的主要内容,如果未能解决你的问题,请参考以下文章
为啥我收到致命错误:未捕获的异常 'GuzzleHttp\Exception\RequestException' 和消息 'cURL 错误 60
致命错误:未捕获的异常“Phalcon\Mvc\Model\Exception”与消息“语法错误,意外令牌>,
致命错误:未捕获的异常“PDOException”,带有消息“SQLSTATE [42000]:语法错误或访问冲突 PHP 和 PDO