Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.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
Mysql 多个动态查找集合中的查找_Mysql_Sql - Fatal编程技术网

Mysql 多个动态查找集合中的查找

Mysql 多个动态查找集合中的查找,mysql,sql,Mysql,Sql,因此,在我的编程语言中有这样一个数组: $animalsToSearch = ['fox', 'cat', 'dog']; 我有一个MySQL数据库表,如下所示: id | value ----+---------------- 1 | dog,elephant 2 | cat,dog 3 | spider,fox,cat 4 | cat 5 | dog,rabit 不幸的是,我还不能将表更改为更具关系性的表 我想从数据库value列中提取数组中的一个项存在的次数。现在

因此,在我的编程语言中有这样一个数组:

$animalsToSearch = ['fox', 'cat', 'dog'];
我有一个MySQL数据库表,如下所示:

id  | value
----+----------------
1   | dog,elephant
2   | cat,dog
3   | spider,fox,cat
4   | cat
5   | dog,rabit
不幸的是,我还不能将表更改为更具关系性的表

我想从数据库
value
列中提取数组中的一个项存在的次数。现在,最明显的方法是:

<?php
$count = [];

foreach (['fox', 'cat', 'dog'] as $animal) {
    $count[$animal] = some_function_that_gets_the_data($animal);
}

ysth的解决方案
解释
'd

id  select_type  table       partitions    type  possible_keys  key   key_len  ref    rows       filtered  Extra
1   PRIMARY      <derived2>  NULL          ALL   NULL           NULL  NULL     NULL   2          100.00    Using temporary; Using filesort
1   PRIMARY      animal      NULL          ALL   NULL           NULL  NULL     NULL   1,879,296  100.00    Using where; Using join buffer (Block Nested Loop)
2   DERIVED      NULL        NULL          NULL  NULL           NULL  NULL     NULL   NULL       NULL      No tables used
3   UNION        NULL        NULL          NULL  NULL           NULL  NULL     NULL   NULL       NULL      No tables used
id选择\u类型表分区类型可能的\u键键\u len ref行过滤额外
1主空所有空2 100.00使用临时;使用文件排序
1主要动物空所有空1879296 100.00使用where;使用联接缓冲区(块嵌套循环)
2个派生空值未使用表
3 UNION NULL未使用任何表

根据您的列表加入:

select animallist.animal, count(*) as times
from (
    select 'fox' as animal union all select 'cat' union all select 'dog'
) animallist
join animal on find_in_set(animallist.animal, animal.value)
group by animallist.animal
你可以试着强迫它只阅读动物一次,我不知道这会让它更快还是更慢:

select straight_join animallist.animal, count(*) as times
from animal on find_in_set(animallist.animal, animal.value)
join (
    select 'fox' as animal union all select 'cat' union all select 'dog'
) animallist
group by animallist.animal

传统索引无法帮助改进
FIND\u IN_SET()
的性能,就像索引无法帮助改进
SUBSTRING()
like
的通配符一样。性能永远不会好,而且随着表的增大,性能会变得更差

但全文索引可以有所帮助

ALTER TABLE animals ADD FULLTEXT INDEX (value);

mysql> select * from animals where match(value) against ('rabbit' in boolean mode);
+----+--------------+
| id | value        |
+----+--------------+
|  5 | doggy,rabbit |
+----+--------------+
1 row in set (0.00 sec)

mysql> select * from animals where match(value) against ('rabbit doggy' in boolean mode);
+----+----------------+
| id | value          |
+----+----------------+
|  5 | doggy,rabbit   |
|  1 | doggy,elephant |
|  2 | kittycat,doggy |
+----+----------------+
在我的测试中,我让所有动物的名字至少有4个字符,因为默认的
ft\u min\u word\u len
是4个字符。短于此的单词不会被全文索引索引


阅读上的章节了解更多信息。

是的,有更好的方法。不要在SQL中存储逗号分隔的值。使用一个单独的表,每个值一行。我担心你错过了我的评论“不幸的是,我无法将表更改为更相关的(但)。”这是我从以前的开发人员那里继承的系统。有时我认为有一个人在公司之间漫游,破坏数据库,让其他倒霉的开发人员“继承”他的演讲很有趣。不过,我必须按动物添加
分组
,才能将其分组。唯一的问题是它需要很长时间运行(2秒),而我的原始帖子查询大约需要30毫秒:(对不起,忘记了。再过2秒,
explain select…
show是什么?我已经将它添加到了我的原始帖子中(为了便于阅读,还以逗号添加到180万的数字中)。添加了一个可选的连接类型no将允许find_in_set()执行除表扫描以外的任何操作。无论使用哪种联接类型,性能都将非常糟糕。
ALTER TABLE animals ADD FULLTEXT INDEX (value);

mysql> select * from animals where match(value) against ('rabbit' in boolean mode);
+----+--------------+
| id | value        |
+----+--------------+
|  5 | doggy,rabbit |
+----+--------------+
1 row in set (0.00 sec)

mysql> select * from animals where match(value) against ('rabbit doggy' in boolean mode);
+----+----------------+
| id | value          |
+----+----------------+
|  5 | doggy,rabbit   |
|  1 | doggy,elephant |
|  2 | kittycat,doggy |
+----+----------------+