mysqlクエリ効率の問題

WBOY
WBOYオリジナル
2016-08-18 09:16:151294ブラウズ

問題は次のとおりです:
データベース内のフィールドのデータは、1,2,3,4,5, のようにカンマで区切られて保存されます。
クエリ中に渡されるパラメータは、次のような配列です:array (1,2 );
私の愚かな方法は、この配列をループし、次に like を使用して結合することです。次のようになります。 リーリー

しかし、データ量が多い場合、この効率は低すぎます。もっと効果的な方法はありますか?ありがとう。 。

返信内容:

問題は次のとおりです:

データベース内のフィールドのデータは、1,2,3,4,5, のようにカンマで区切られて保存されます。
クエリ中に渡されるパラメータは、次のような配列です:array (1,2 );
私の愚かな方法は、この配列をループし、次のように like を使用して結合することです。 リーリー
しかし、データ量が多い場合、この効率は低すぎます。もっと効果的な方法はありますか?ありがとう。 。

リーリー

1. フィールドのタイプを SET に変更します。FINd_IN_SET を使用すると、like を使用するよりもはるかに高速になりますが、フィールドに対して使用する場合はテーブル全体をスキャンする必要があります。 SET タイプにはいくつかの制限があります。SET は、小さな値範囲、固定値、および全体的なクエリを含む状態コレクションに適していることが推奨されます。たとえば、ある人が中国のどの省を訪れたかを記録します。2 人の人が同じ省を訪れたかどうかを直接比較したり、違いを直接取得したりできます。どの人が特定の省のみを訪れたかを効率的にクエリできますが、確認することもできます。特定の州または特定の州を訪れた人々は、依然としてすべてのフォームをスキャンしています。

リーリー

SQL> SELECT FIND_IN_SET('b','a,b,c,d');SELECT FIND_IN_SET('b','a,b,c,d')2

2.
用中间(映射)表,可以借助索引提高查询效率。

不管怎么写,怎么改,用函数也好,这样的数据结构稍微量大效率都很低,索引几乎用不上了
只能改下你们的储存方式,不要把1,2,3,4,5,这种放到一个字段,分开来,或者用nosql

可以考虑下MySQL的正则查询

重新设计数据库吧!!!无论怎么说 字符串匹配的花销都不小。把cate字段抽出来形成一个新的关系表

如果查询的频繁建议缓存数据后用程序来查缓存或者重新设计表,MYSQL里面用正则效率很低的。

你应该去问设计数据表的那个人。

建议修改数据存储格式吧....不是说这么存问题有多大

而是这么存了之后却又需要快捷高效的查...那势必就是自己给自己添堵了 能调整尽快调整

where cate like '%1,%' or cate like '%2,%' 这个条件本身有两个问题都导致无法使用索引:
1、or条件; 2、like '%...'格式。
针对这个查询做优化的:
1、or改为union all
2、在程序里做模糊查询, 将所有数据取出来(或者按10%取,取10次),循环做strpos的模糊匹配。 因为php的array操作时非常快速的,所以这样操作,会比直接入库查询快,但是会耗内存。
另外这样的话,分页这些,也就只有在程序里做了。

其实这个数据库设计是有问题的, 将'1,2,3..'这种格式的字符串设计成字段,mysql效率很低,建议根据位运算去设计cate字段,数据多的话,cate可以为bigint, 这样查询会非常快,也省去了like、 or这些mysql的瓶颈。

不建议使用mysql自带的函数,没太明白你说的1,2 1,2,3,4,5 是具体的什么意思,我猜可能是每条记录所属的类型是哪些,
例如:

<code>老九门 是哪些?包括 语文、数学、英语、化学、生物、物理、地理、历史、政治
这九门都有一个类型是 “老九门”,那么这九门里又有理科和文科,
老九门、理科、文科分别是1、2、3
那么 语文、数学、英语的类型字段是1,2,3
    化学、物理、生物的类型字段是1,2
    地理、历史、政治的类型字段是1,3</code>

(建议不要把业务逻辑放到mysql中处理,mysql字段类型越简单越好,下面会用到)

<code>语文、数学、英语、化学、生物、物理、地理、历史、政治已经有了各自的类型所属
是否考虑将1,2,3  1,2  1,3 定义成数组格式呢
这里应用php的写法
            $arr = array(
                        1=>array(1,2,3),
                        2=>array(1,2),
                        3=>array(1,3)
                    );
 在往表中插入数据时,你的cate字段就存1 2 3就可以了,到时候直接查询1或者2或者3就可以了,业务逻辑去脚本程序
 中处理,不要在mysql中做太多的处理,越简单越好
 如果还是不太懂的话 也可以
             $arr = array(
                        '1,2,3'=>1,
                        '1,2'=>2,
                        '1,3'=>3
                    );
            在程序中处理完后再去查相应的mysql数据就可以了</code>
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。