Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使mysqli查询在PHP中运行得更快?_Php_Mysql_Sql_Time_Mysqli - Fatal编程技术网

如何使mysqli查询在PHP中运行得更快?

如何使mysqli查询在PHP中运行得更快?,php,mysql,sql,time,mysqli,Php,Mysql,Sql,Time,Mysqli,$networks是多个值用逗号分隔的字符串。 例如: $networks = "Programming,Movies,Hollywood". (There can be around 150 values or more.) 现在Mysql查询转到这里: $query = "SELECT * FROM table WHERE ( isActive = 1 AND isDeleted = 0 AND

$networks是多个值用逗号分隔的字符串。 例如:

$networks = "Programming,Movies,Hollywood". (There can be around 150 values or more.)    
现在Mysql查询转到这里:

$query = "SELECT * FROM table 
          WHERE ( isActive = 1 AND 
                  isDeleted = 0 AND 
                  onid = '0' AND 
                  question = 0 AND 
                  ( ".$networkqur." )
                ) 
ORDER BY id DESC
LIMIT 0,100;
此处$networkqur为:

$network = explode(',',$networks);

$networkqur = '';
for( $i = 0; $i < count($network); $i++ ){
    $networkqur .= 'networks LIKE "%'.$network[$i].'%"';
    if( $i != count($network) - 1 ){
        $networkqur .= ' OR ';
    }
}
有效查询变成:

$query = "SELECT * FROM posts
          WHERE ( isActive = 1 AND 
                  isDeleted = 0 AND 
                  onid = '0' AND 
                  question = 0 AND 
                   ( networks LIKE "%Programming%" OR 
                     networks LIKE "%Movies%" OR 
                     networks LIKE "%Hollywood% ) 
                   ) 
          ORDER BY id DESC
          LIMIT 0,100;
现在我们可以看到,查询中可能有150个OR条件,最后有多个带有排序的and条件

是否可以替换此特定查询或以任何其他更快的方式执行它?

您在设计或数据库中犯了一个可怕的错误。在设计数据库时,应该遵循六条数据库规范化规则,您已经打破了第一条也是最重要的规则——在每列中只存储一条信息

如果不在数据库上实现复杂的全文索引系统,就无法优化当前的设计。此外,无法执行关系完整性(检查是否只存储允许的
网络
值。您不能索引这些值,也不能在联接中使用它们。此外,您还存在一个嵌入式字符串问题,搜索(例如)“Holly”将匹配“Holly”、“Hollywood”和“Holly Hunter”


相反,您应该将
networks
列拆分为一个单独的表名
post\u networks
,其中包含
post\u id
network
。每个post和network组合添加一行,在
(post\u id,network)
上添加一个主键,可能在
(network,post\u id)上添加一个主键
,您将能够更快、更安全地执行此查询(以及更多查询)。

如果您的术语列表相对固定(即非用户生成)然后,这里的一个解决方案是构建您自己的索引表,然后对其进行检查。如果在添加/编辑主数据时只构建索引上的接触点,这将大大提高
SELECT
语句的速度。因此,您的索引表将具有每条记录的主键(理想情况下是一个
主键
),然后是对您正在查找的内容的引用。然后您可以将
索引
添加到术语列,您的速度应该会显著提高,因为您正在对索引列进行查找


理想情况下,您永远不应该查找未索引的数据。

您需要将
网络
分解到自己的表中,并开始使用
连接
s和
中的
^但您不认为分解到其他表会增加复杂性和时间吗?我认为没有任何更快的解决方案。您可以使用regexp,但我认为它甚至要慢一点(但在本例中更容易编写)。您使用的是
如“…%”
您几乎无法加快这些查询的速度-它们不能使用索引。您应该切换到全文搜索,至少可以索引。这是另一个问题“我正在崩溃,现在它让我的生活变得悲惨。我如何让它更快/更容易/更简单?”?“问题。答案是,一如既往,不要打破第一范式。正如我所说,一个用户可以有150个网络,这意味着在单独的用户-网络关系表中,1k个用户可以有100k个字段。你不认为迭代100k行会有困难吗?仅仅因为你的表非常小(100000行)没有理由不正确创建结构。事实上,我会创建另一个更小的表(150行)来列出允许的网络,然后将
post_networks
中的
network
字段作为外键“保护”到较小的查找表中。
$query = "SELECT * FROM posts
          WHERE ( isActive = 1 AND 
                  isDeleted = 0 AND 
                  onid = '0' AND 
                  question = 0 AND 
                   ( networks LIKE "%Programming%" OR 
                     networks LIKE "%Movies%" OR 
                     networks LIKE "%Hollywood% ) 
                   ) 
          ORDER BY id DESC
          LIMIT 0,100;