Php 确定值是否在表中的最有效方法

Php 确定值是否在表中的最有效方法,php,sql,performance,Php,Sql,Performance,我经常遇到这样的情况:我想确定一个值是否在表中。查询通常在短时间内发生,并且搜索类似的值,因此我希望以最有效的方式执行此操作。我现在拥有的是 if($statment = mysqli_prepare($link, 'SELECT name FROM inventory WHERE name = ? LIMIT 1'))//name and inventory are arbitrarily chosen for this example { mysqli_stmt_bind_param

我经常遇到这样的情况:我想确定一个值是否在表中。查询通常在短时间内发生,并且搜索类似的值,因此我希望以最有效的方式执行此操作。我现在拥有的是

if($statment = mysqli_prepare($link, 'SELECT name FROM inventory WHERE name = ? LIMIT 1'))//name and inventory are arbitrarily chosen for this example
{
    mysqli_stmt_bind_param($statement, 's', $_POST['check']);
    mysqli_stmt_execute($statement);
    mysqli_stmt_bind_result($statement, $result);
    mysqli_stmt_store_result($statement);//needed for mysqli_stmt_num_rows
    mysqli_stmt_fetch($statement);
}
if(mysqli_stmt_num_rows($statement) == 0)
        //value in table
else
        //value not in table
是否需要调用所有的
mysqli\u stmt.*
函数?如中所述,对于
mysqli\u stmt\u num\u rows()
要工作,必须从数据库服务器下载整个结果集。我担心这会浪费时间,因为我知道有1行或0行。使用SQL
count()
函数而不使用mysqli\u stmt\u store\u result()会更有效吗?还有其他想法吗

我注意到上面说“一个准备好的语句或一个参数化的语句被用来高效地重复执行同一个语句”。什么是高效的?同一句话的意思是什么?例如,如果两个单独的准备好的语句被评估为相同,它还会更有效吗

顺便说一句,我正在使用MySQL,但不想添加标签,因为解决方案可能不是特定于MySQL的

if($statment = mysqli_prepare($link, 'SELECT name FROM inventory WHERE name = ? LIMIT      1'))//name and inventory are arbitrarily chosen for this example
{
    mysqli_stmt_bind_param($statement, 's', $_POST['check']);
    mysqli_stmt_execute($statement);
    mysqli_stmt_store_result($statement);
}
if(mysqli_stmt_num_rows($statement) == 0)
    //value not in table
else
    //value in table
我相信这已足够。请注意,我切换的//值不在表中
和//表中的值。

这是内存缓存真正擅长的事情。类似的东西应该比大多数微优化尝试(伪代码!)更有效:


查看或选择各种选项。

这取决于您搜索的字段类型。确保在该字段上有索引,并且该索引适合内存。如果是,则从限制1处选择计数(*)。重要的部分是
限制1
,它可以防止不必要的查找。您可以运行
EXPLAIN SELECT…
查看使用了哪些索引,并可能会提示或禁止其中的一些索引,这取决于您自己<代码>计数(*)工作速度非常快,它通过设计返回结果非常快地进行优化(仅限MyISAM,对于InnoDB,由于ACID的原因,整个内容有点不同)。
COUNT(*)
SELECT
之间的主要区别在于
COUNT
不执行任何数据读取,而(*)不关心某个字段是否为空,只需按最合适的索引(内部选择)对行进行计数。实际上,我可以建议,即使对于InnoDB,这也是一种最快的技术

还有用例问题。如果要插入唯一值,请对该字段进行约束并使用
插入忽略
,如果要删除表中可能不存在的值,请运行
删除忽略
,并对
更新忽略
执行相同操作

查询分析器自行定义两个查询在缓存上是否相同,并管理查询缓存,您不必担心这一点

准备好的查询和常规查询的不同之处在于,第一个查询分别包含规则和数据,所以analyzer可以定义哪些数据是动态的,并且可以更好地处理这些数据、进行优化等等。它可以对常规查询执行相同的操作,但对于准备好的查询,我们说稍后将重用它,并提示哪些数据是可变的,哪些是固定的。我不太擅长MySQL内部,所以你可以在更具体的网站上问这样的问题,以便简单地了解细节


注意:MySQL中准备好的语句是会话全局的,所以在会话结束后,它们在端点中被定义,然后被释放。确切的行为和可能的内部MySQL缓存是一个额外调查的主题。

可能重复@DaveChen您链接到的文章的哪一部分包含重复的信息?
它的高效性是什么
,它确实有意义,SQL
解析器
解析更少的信息和更多的数据。SQL解析器为什么/如何解析更少的信息和更多的数据?我不是一个反对者,但保持memcache和mysql处于一致状态似乎不是一项简单的任务,特别是如果您的web机器和副本集很少的话。其次,最初的问题并不完全是关于加速技术,因此缓存看起来是下一步优化,在这种情况下不是最好的,只需想象10k个可能的键,每个键的长度为16char(甚至是8bit/char)。与memcache键相比,最好放在这个内存db索引中。
function check_if_value_is_in_table($value) {
  if ($cache->contains_key($value)) {
    return $cache->get($value);
  }
  // run the SQL query here, put result in $result
  // note: I'd benchmark if using mysqli_prepare actually helps
  // performance-wise
  $cache->put($value, $result);
  return $result;
}