mysqli致命错误:查询/预准备语句中没有使用索引

时间:2014-08-27 11:44:58

标签: php mysqli prepared-statement

我想使用mysqli执行一个简单的预处理语句,但它不会工作。

我有这张桌子:

CREATE TABLE IF NOT EXISTS `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(100) COLLATE latin1_german2_ci NOT NULL,
  `password` varchar(100) COLLATE latin1_german2_ci NOT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci AUTO_INCREMENT=4 ;

想要打印特定电子邮件的ID。

$mysqli = new mysqli($server,$user,$pass,$db);

if(mysqli_connect_errno()) {
    echo "Connection Failed: " . mysqli_connect_errno();
    exit();
 }
 $user = "test@dada.com";
 $pass = "dada";
/* Create a prepared statement */
if($stmt = $mysqli -> prepare("SELECT * FROM account WHERE email=?
AND password=?")) {

  /* Bind parameters
     s - string, b - blob, i - int, etc */
  $stmt -> bind_param("ss", $user, $pass);

  /* Execute it */
  $stmt -> execute();

  /* Bind results */
  $stmt -> bind_result($result);

  /* Fetch the value */
  $stmt -> fetch();

  echo $user . "id of user is " . $result;

  /* Close statement */
  $stmt -> close();
}

/* Close connection */
$mysqli -> close();

但我得到以下错误:

  

致命错误:未捕获的异常' mysqli_sql_exception'带有消息'查询/预准备语句中没有使用索引SELECT * FROM account WHERE email =?和密码=?' mysqli_stmt-> execute()#1 {main}

2 个答案:

答案 0 :(得分:1)

我认为你必须这样做:

CREATE TABLE IF NOT EXISTS `account` (
  `id` PRIMARY KEY int(11) NOT NULL AUTO_INCREMENT,
   // the rest

上面的代码使您的表的id字段为PRIMARY KEY,因此它永远不会重复,它仍然是您的表的索引。

答案 1 :(得分:0)

您的问题是,如果不使用 INDEX,您正在执行的查询将效率低下。

SELECT * FROM account WHERE email=? AND password=?

您在 WHERE 子句中使用的两个字段中的任何一个都没有索引。一种解决方案是在两个字段上都创建一个索引,这将使错误消失。

ALTER TABLE account ADD INDEX `index_on_email_and_password` (email, password);

在许多情况下,您知道 INDEX 不会提高性能,因此您可以放心地忽略此错误。为此,请替换以下代码行:

mysqli_report(MYSQLI_REPORT_ALL);

其中之一

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
// or 
mysqli_report(MYSQLI_REPORT_ALL & ~MYSQLI_REPORT_INDEX);

这将继续报告正常的 SQL 错误,但它会忽略所有关于错误索引的警告。