Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/275.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
Php 类MySQL函数_Php_Html_Mysql_Sql - Fatal编程技术网

Php 类MySQL函数

Php 类MySQL函数,php,html,mysql,sql,Php,Html,Mysql,Sql,在“我的html”页面上,用户可以选择输入文本字符串、选中标记选项或同时执行这两项操作。然后将这些数据放在显示数据的mysql查询中 允许用户输入字符串这一事实意味着我正在mysql查询中使用LIKE函数 如果我错了,请纠正我,但我相信LIKE函数可以大大降低查询速度。 关于上述语句,我想知道like函数中的空字符串是否会产生影响,例如: select * from hello; select * from hello where name like "%%"; 如果它真的有很大的不同(我相信

在“我的html”页面上,用户可以选择输入文本字符串、选中标记选项或同时执行这两项操作。然后将这些数据放在显示数据的mysql查询中

允许用户输入字符串这一事实意味着我正在mysql查询中使用LIKE函数

如果我错了,请纠正我,但我相信LIKE函数可以大大降低查询速度。 关于上述语句,我想知道like函数中的空字符串是否会产生影响,例如:

select * from hello;
select * from hello where name like "%%";
如果它真的有很大的不同(我相信这个数据库会越来越大),你对如何处理这个问题有什么想法

我的第一个想法是,我将有两个问题: 具有类似功能的一个 还有一个没有类似的功能。根据用户输入的内容,将调用正确的查询

因此,例如,如果用户将搜索框留空,则不需要like函数,因此它将发送一个空字符,并且当if语句看到有空字符时,它将选择另一个选项(没有like函数)


有更好的方法吗?

一般来说,类
函数的速度会很慢,除非它以固定字符串开头,并且列有索引。如果像'foo%'这样执行
,它可以使用索引查找以
foo
开头的所有行,因为MySQL索引使用B树。但是像'%foo'
这样的
不能使用索引,因为B-树只优化寻找前缀;这必须对整个表进行顺序扫描

即使使用带有前缀的版本,性能改进也取决于前缀减少了多少行数。如果像'foo%bar'
这样执行
,并且90%的行以
foo
开头,则仍需扫描90%的表,以测试它们是否以
bar
结尾


由于像“%”这样的
没有固定的前缀,因此它将对表执行完全扫描,即使实际上没有任何内容可搜索。最好是您的PHP脚本测试用户是否提供了搜索字符串,如果没有可搜索的内容,则省略类似于
的测试。

使用mysql软件发行版中的World database示例,我首先对带有和不带
的查询进行了一个简单的
解释,其中
子句没有过滤效果:

mysql> explain select * from City;

mysql> explain select * from City where true;

mysql> explain select * from City where Name = Name;
在前三种情况下,结果如下:

+----+--------------+-------+------+----------------+-----+---------+-----+------+-------+
 | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------+-------+------+----------------+-----+---------+-----+------+-------+
|  1 | SIMPLE      | City  | ALL   | NULL          | NULL | NULL    | NULL | 4080 |       |
+----+--------------+-------+------+----------------+-----+---------+-----+------+-------+
对于最后一个查询,我得到了以下结果:

mysql> explain select * from City where Name like "%%";

+----+--------------+-------+------+----------------+-----+---------+-----+------+-------+
 | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra       |
+----+--------------+-------+------+----------------+-----+---------+-----+------+-------+
|  1 | SIMPLE      | City  | ALL   | NULL          | NULL | NULL    | NULL | 4080 | Using where |
+----+--------------+-------+------+----------------+-----+---------+-----+------+-------+
您可以看到,对于这个特定的查询,where条件没有被优化掉

我还进行了几次测量,以检查是否存在明显差异,但:

  • 该表只有4080行,我使用了自交叉连接来延长计算时间

  • 我使用
    包含
    子句来减少显示开销(1)

测量结果:

mysql> select c1.Name, c2.Name from City c1, City c2 where concat(c1.Name,c2.Name) = concat(c1.Name,c2.Name) having c1.Name = ""; 
Empty set (5.22 sec)
上述查询以及带有
true
c1.Name=c1.Name
的查询在不到0.1秒的间隔内执行得相当合理

mysql> reset query cache;

mysql> select c1.Name, c2.Name from City c1, City c2 where concat(c1.Name,c2.Name) like "%%" having c1.Name = "";
Empty set (13.80 sec)
在多次运行时(在查询缓存重置之间),这一次也花费了大约相同的时间(2)

很明显,查询优化器没有看到后面这种情况的机会。结论是,您应该尽量避免使用该子句,即使它不会改变结果集


(1) :由于查询中的数据合并后发生子句筛选,我假设它不应更改实际的查询计算负载率

(2) :有趣的是,我最初尝试了一个简单的
where c1.Name,比如“%%”“
,并绕过
5.0
秒。计时结果,这让我尝试了一个更详细的条款。我不认为这个结果改变了总体结论;可能在这种非常特殊的情况下,过滤实际上具有有益的效果。希望mysql专家能够解释这一结果

我相信LIKE函数可以大大降低查询速度

我希望情况并非如此。测试它有多难

无论运行哪个版本的查询,DBMS都必须检查表中的每一行。这需要CPU做一些额外的工作,但对于大型表,磁盘I/O将是限制因素<代码>如“%”
将丢弃具有空值的行-因此可能会减少DBMS需要保留在结果集中/传输到客户端的数据量,这可能会大大节省数据

正如Barbar所说,提供一个没有前导通配符的表达式将允许DBMS使用索引(如果有索引的话),这将对性能产生重大影响


很难从您的问题中分辨出来(您没有提供太多的示例查询/数据,也没有提供应用程序的任何细节),但您的问题的解决方案可能是

yep,如果没有要检查的字符串,则不检查“%”之类的
,这显然是一种很好的方法:)这取决于查询编译器的智能程度。如果它认识到像“%”这样的
将匹配所有内容,并将其从语句中删除,那么您的两个查询的执行情况将相同。您是否尝试过对此进行测试并将其付诸实践?我想它已经消毒了。我将使用一个语句来评估用户是否提交了任何内容,并基于此执行逻辑。你问了一个广泛的问题:“我能做得更好吗?”。答案是肯定的。你总是可以的。我现在无法真正测试它,因为我没有那么多的数据。查询时间的差异对他们两个来说都可以忽略不计。它似乎不够聪明,无法像“%”那样省略
。我刚刚从用户名为“%”的用户中尝试了
select*
,该用户位于一个有330万的表中