MySQL のフルテキスト インデックスが、あいまい一致クエリのような遅い問題をどのように解決するかについて話しましょう。
ファジー クエリ (名前に「xiao」が含まれるユーザーをクエリする場合など)、一般的な書き方は「%xiao%」のようなものです。MySQL ではテーブル全体をスキャンするため、データ量が少ないので良いですが、フルテーブルスキャンも速いですが、データが増えると遅くなり、ESの読み込みが非常に重いです。この記事では、あいまい一致クエリのように遅い場合の解決策である MySQL フルテキスト インデックスを紹介します。
要件
単語をクエリするにはあいまい一致が必要です
select * from t_phrase where LOCATE('Chan',phrase) = 0 ;
select * from t_chinese_phrase where instr(phrase,'Chan') > 0;
select * from t_chinese_phrase where フレーズ '%长%'
実行計画を説明して見てください
結果からわかりますインデックスは設定されていますが、クエリを実行するとインデックスが無効になるというフレーズを作成しましたが、そのインデックスが無効であることを説明します。 ######理由: mysql のインデックスは B ツリー構造になっており、データのあいまいクエリ時に InnoDB が "%xx" を使用するとインデックスが失敗します (ここでは詳細は説明しません)
クエリ時間の観点から見ると、費やした時間: 90ms
現在のデータ量: 93230 (9.3W) はすでに 90ms を必要としています。この時間は許容できません。データ量が増加すると、この時間はさらに増加します。
解決策:
データ量が大きくない場合は、mysql の全文インデックスを使用します;データ量が比較的多い場合、またはフルテキスト インデックスを使用します。 mysql のテキスト インデックスは期待を満たしていません。ES の使用を検討してください。フルテキスト インデックスはじめに以下は主に MySQL のフルテキスト インデックスに関連しています。
1. 開発の歴史
- MySQL の古いバージョンのフルテキスト インデックスは char でのみ使用できます。 、MyISAM ストレージ エンジンの varchar および text フィールド。
- #全文検索
- はデータベースに保存されます。本全体または記事全体のコンテンツから情報を検索します。全文中の章、節、段落、単語などの情報を必要に応じて取得でき、各種統計や分析も行うことができます
大量のデータに対してフルテキスト インデックスを設定する必要がある場合は、最初にデータを追加してからインデックスを作成することをお勧めします。
1. テーブル作成時にフルテキスト インデックスを作成する
create table 表名( 字段名1, 字段名2, 字段名3, 字段名4, FULLTEXT full_index_name (字段名) )ENGINE=InnoDB;
2. 既存のテーブルにフルテキスト インデックスを追加する
フルテキスト インデックスインデックスを作成するテーブル名 (フィールド名) の名前;例:
create table t_word ( id int unsigned auto_increment comment '自增id' primary key, uid char(32) not null comment '32位唯一id', word varchar(256) null comment '英文单词', translate varchar(256) null ); create fulltext index full_idx_translate on t_word (translate); create fulltext index full_idx_word on t_word (word); INSERT INTO t_word (id, uid, word, translate) VALUES (1, '9d592499c65648b0a9519206688ef3f9', 'lion', '狮子'); INSERT INTO t_word (id, uid, word, translate) VALUES (2, 'ce26ac4239514bc6af481bcb1d9b67df', 'panda', '熊猫'); INSERT INTO t_word (id, uid, word, translate) VALUES (3, 'a7d6042853c44904b68275daafb44702', 'tiger', '老虎'); INSERT INTO t_word (id, uid, word, translate) VALUES (4, 'f13bd0a8ecea44fc9ade1625eeb4cc3c', 'goat', '山羊'); INSERT INTO t_word (id, uid, word, translate) VALUES (5, '27d5cbfc93a046388d712085e567474f', 'sheep', '绵羊'); INSERT INTO t_word (id, uid, word, translate) VALUES (6, 'ed35df138cf348aa937781be8ee21cbf', 'lamb', '羊羔'); INSERT INTO t_word (id, uid, word, translate) VALUES (7, 'fba5861d9527440990276e999f47ef8f', 'buffalo', '水牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (8, '3a72e76f210841b1939fff0d3d721375', 'bull', '公牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (9, '272e0b28ea7a48248a86f17533bf9943', 'cow', '母牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (10, '47127adface54e418e4c1b9980af6d16', 'calf', '小牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (11, '10592499c65648b0a9519206688ef3f9', 'little lion', '小狮子'); INSERT INTO t_word (id, uid, word, translate) VALUES (12, '1bf095110b634a01bee5b31c5ee7ee0c', 'little cow', '母牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (13, '4813e588cde54c30bd65bfdbb243ad1f', 'little calf', '小小牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (14, '5e377e281ad344048b6938a638b78ccb', 'little bull', '小公牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (15, '2855ad0da2964c7682c178eb8271f13d', 'little buffalo', '小水牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (16, '72f24c9a77644d57a36f3bdf2b8116b0', 'little lamb', '小羊羔'); INSERT INTO t_word (id, uid, word, translate) VALUES (17, '2d592499c65648b0a9519206688ef3f9', 'I''m a big lion', '我是一只大狮子');
3. フルテキスト インデックスを削除します
alter table table name dropindexインデックス名;4. フルテキスト インデックスは、自然言語モードでは
構文
MATCH(col1,col2,...) AGAINST(expr[search_modifier]) search_modifier: { IN NATURAL LANGUAGE MODE | IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION | IN BOOLEAN MODE | WITH QUERY EXPANSION }
自然言語モードは、MySQL
default の全文検索モードです。自然言語モードでは演算子を使用できず、出現する必要があるキーワードや出現してはならないキーワードなどの複雑なクエリを指定できません。 // 默认是使用 in natural language mode
select * from t_word where match(word) against ('lion');
// 或者 显示写
select * from t_word where match(word) against ('lion' in natural language mode);
ブール モード
あなた演算子を使用でき、キーワードを出現させるか出現させないか、キーワードの重みが高いか低いかを指定するなど、複雑なクエリをサポートできます。 ブール モードの使用を推奨します
#- | |
>(記号より大きい) | ランク値を含めて増やすと、クエリ結果が高くなります |
##< | ランク値を含めたり減らしたりします。クエリ結果は後で表示されます。 |
() | 単語を部分式にグループ化します (これらを部分式として含めることができます)。グループ、除外、ランク付けなど)。 |
~ | 否定的な単語の値をランク付けします。 |
# ワイルドカード文字は単語の末尾にあります。 | |
"" | フレーズを定義します (フレーズ全体が一致して含めるか除外する個々の単語のリストではありません)。 |
示例: // 默认是使用 in natural language mode select * from t_word where match(word) against ('lion'); // 或者 显示写 select * from t_word where match(word) against ('lion' in natural language mode); ログイン後にコピー ログイン後にコピー // 排除包含lion记录、查询出包含cow或者little的记录,提升包含calf单词的排名,降低包含cow记录的排名,查询出以go开头的记录 select * from t_word where match(word) against ('-lion cow little >calf <cow go*' in boolean mode) ; ログイン後にコピー 好像问题都解决了, 但是问题才刚开始 回到最开始的需求,我想模糊搜索 select * from t_word where match(word) against('lio' in boolean mode); ログイン後にコピー 预期值:把包含lion的都查询出来 实际结果:啥都没有。 全匹配查询的时候能查询出来 select * from t_word where match(translate) against('小水牛' in boolean mode); ログイン後にコピー 只查询部分查询不出来。如:下面只查询 "小水" 或者"水牛" 都没有数据 select * from t_word where match(translate) against('小水' in boolean mode); ログイン後にコピー 奇怪了,这咋没出来呢?
中文分词与全文索引InnoDB默认的全文索引parser非常合适于Latin,因为Latin是通过空格来分词的。但对于像中文,日文和韩文来说,没有这样的分隔符。一个词可以由多个字来组成,所以我们需要用不同的方式来处理。在MySQL 5.7.6中我们能使用一个新的全文索引插件来处理它们:N-gram parser。 什么是N-gram?在全文索引中,n-gram就是一段文字里面连续的n个字的序列。例如,用n-gram来对“齿轮传动”来进行分词,得到的结果如下: N=1 : '齿', '轮', '传', '动'; N=2 : '齿轮', '轮传', '传动'; N=3 : '齿轮传', '轮传动'; N=4 : '齿轮传动'; ログイン後にコピー 这个上面这个N是怎么去配置的?查一下目前的值show variables like '%token%'; ログイン後にコピー 参数解析:
修改方式方式1: 在my.cnf中修改/添加参数 [mysqld]ngram_token_size = 1 ログイン後にコピー 方式2: 修改启动参数 mysqld --ngram_token_size=1复制代码 ログイン後にコピー
实际使用初始化测试数据这里 create table t_chinese_phrase ( id int unsigned auto_increment comment 'id' primary key, phrase varchar(32) not null comment '词组' ) collate = utf8mb4_general_ci; INSERT INTO t_chinese_phrase (id, phrase) VALUES (278911, '阿昌族'); INSERT INTO t_chinese_phrase (id, phrase) VALUES (279253, '八一南昌起义'); INSERT INTO t_chinese_phrase (id, phrase) VALUES (282316, '昌明'); INSERT INTO t_chinese_phrase (id, phrase) VALUES (282317, '昌盛'); INSERT INTO t_chinese_phrase (id, phrase) VALUES (282318, '昌言'); INSERT INTO t_chinese_phrase (id, phrase) VALUES (286534, '东昌纸'); INSERT INTO t_chinese_phrase (id, phrase) VALUES (291525, '海昌蓝'); INSERT INTO test.t_chinese_phrase (id, phrase) VALUES (346682, '繁荣昌盛'); INSERT INTO test.t_chinese_phrase (id, phrase) VALUES (282317, '昌盛'); INSERT INTO test.t_chinese_phrase (id, phrase) VALUES (287738, '繁盛'); INSERT INTO test.t_chinese_phrase (id, phrase) VALUES (287736, '繁荣'); ログイン後にコピー 添加索引
添加索引: alter table t_chinese_phrase add fulltext ful_phrase (phrase) with parser ngram; ログイン後にコピー 建完索引,我们可以通过查询INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE和INFORMATION_SCHEMA.INNODB_FT_TABLE_TABLE来查询哪些词在全文索引里面。这是一个非常有用的调试工具。如果我们发现一个包含某个词的文档,没有如我们所期望的那样出现在查询结果中,那么这个词可能是因为某些原因不在全文索引里面。比如,它含有stopword,或者它的大小小于ngram_token_size等等。这个时候我们就可以通过查询这两个表来确认。下面是一个简单的例子: # test: 库名 t_chinese_phrase: 表名字 SET GLOBAL innodb_ft_aux_table="test/t_chinese_phrase"; # 查询分词情况 SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; # 查询分词情况 select * from information_schema.innodb_ft_index_table; ログイン後にコピー 查询结果如下:
查询1、使用自然语言模式 NATURAL LANGUAGE MODE 查询
例如,当ngram_token_size = 1 时,(‘繁荣昌盛’)转换为(‘繁 荣 昌 盛’)。下面一个例子: SELECT * FROM t_chinese_phrase WHERE MATCH (phrase) AGAINST ('繁荣昌盛' in natural language mode) ; ログイン後にコピー 2、使用布尔模式(BOOLEAN MODE)查询
例如,当ngram_token_size = 1 时,(‘繁荣昌盛’)转换为(‘”繁荣昌盛“’)。下面一个例子: SELECT * FROM t_chinese_phrase WHERE MATCH (phrase) AGAINST ('繁荣昌盛' in boolean mode) ; ログイン後にコピー 实际使用回到我们最开始的查询需求,看看实际的效果 查询包含了“昌”的数据 SELECT * FROM t_chinese_phrase WHERE MATCH (phrase) AGAINST ('昌' IN boolean MODE) ; SELECT * FROM t_chinese_phrase WHERE MATCH (phrase) AGAINST ('昌' ) order by id asc; ログイン後にコピー 可以看到结果:目前“昌”在任意位置都能被查询到。 查询执行计划如下: 耗时31ms(不走索引是90ms), 注意点1、自然语言全文索引创建索引时的字段需与查询的字段保持一致,即MATCH里的字段必须和FULLTEXT里的一模一样; 2、自然语言检索时,检索的关键字在所有数据中不能超过50%(即常见词),则不会检索出结果。可以通过布尔检索查询; 3、在mysql的stopword中的单词检索不出结果。可通过 SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD ログイン後にコピー 查询所有的stopword。遇到这种情况,有两种解决办法: (1)stopword一般是mysql自建的,但可以通过设置ft_stopword_file变量为自定义文件,从而自己设置stopword,设置完成后需要重新创建索引。但不建议使用这种方法; (2)使用布尔索引查询。 4、小于最短长度和大于最长长度的关键词无法查出结果。可以通过设置对应的变量来改变长度限制,修改后需要重新创建索引。 myisam引擎下对应的变量名为ft_min_word_len和ft_max_word_len innodb引擎下对应的变量名为innodb_ft_min_token_size和innodb_ft_max_token_size 5、MySQL5.7.6之前的版本不支持中文,需使用第三方插件 6、全文索引只能在 InnoDB(MySQL 5.6以后) 或 MyISAM 的表上使用,并且只能用于创建 char,varchar,text 类型的列。 【相关推荐:mysql视频教程】 以上がMySQL のフルテキスト インデックスが、あいまい一致クエリのような遅い問題をどのように解決するかについて話しましょう。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。 このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
![]() ホットAIツール![]() Undresser.AI Undressリアルなヌード写真を作成する AI 搭載アプリ ![]() AI Clothes Remover写真から衣服を削除するオンライン AI ツール。 ![]() Undress AI Tool脱衣画像を無料で ![]() Clothoff.ioAI衣類リムーバー ![]() Video Face Swap完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。 ![]() 人気の記事
アサシンのクリードシャドウズ:シーシェルリドルソリューション
3週間前
By DDD
Windows11 KB5054979の新しいものと更新の問題を修正する方法
2週間前
By DDD
Atomfallのクレーンコントロールキーカードを見つける場所
3週間前
By DDD
<🎜>:Dead Rails-すべての課題を完了する方法
4週間前
By DDD
Atomfall Guide:アイテムの場所、クエストガイド、およびヒント
1 か月前
By DDD
![]() ホットツール![]() メモ帳++7.3.1使いやすく無料のコードエディター ![]() SublimeText3 中国語版中国語版、とても使いやすい ![]() ゼンドスタジオ 13.0.1強力な PHP 統合開発環境 ![]() ドリームウィーバー CS6ビジュアル Web 開発ツール ![]() SublimeText3 Mac版神レベルのコード編集ソフト(SublimeText3) ![]() ホットトピック
Gmailメールのログイン入り口はどこですか?
![]() ![]()
Java チュートリアル
![]() ![]()
CakePHP チュートリアル
![]() ![]()
Laravel チュートリアル
![]() ![]()
PHP チュートリアル
![]() ![]() ![]() 次の手順でphpmyadminを開くことができます。1。ウェブサイトコントロールパネルにログインします。 2。phpmyadminアイコンを見つけてクリックします。 3。MySQL資格情報を入力します。 4.「ログイン」をクリックします。 ![]() MySQLはオープンソースのリレーショナルデータベース管理システムであり、主にデータを迅速かつ確実に保存および取得するために使用されます。その実用的な原則には、クライアントリクエスト、クエリ解像度、クエリの実行、返品結果が含まれます。使用法の例には、テーブルの作成、データの挿入とクエリ、および参加操作などの高度な機能が含まれます。一般的なエラーには、SQL構文、データ型、およびアクセス許可、および最適化の提案には、インデックスの使用、最適化されたクエリ、およびテーブルの分割が含まれます。 ![]() データベースとプログラミングにおけるMySQLの位置は非常に重要です。これは、さまざまなアプリケーションシナリオで広く使用されているオープンソースのリレーショナルデータベース管理システムです。 1)MySQLは、効率的なデータストレージ、組織、および検索機能を提供し、Web、モバイル、およびエンタープライズレベルのシステムをサポートします。 2)クライアントサーバーアーキテクチャを使用し、複数のストレージエンジンとインデックスの最適化をサポートします。 3)基本的な使用には、テーブルの作成とデータの挿入が含まれ、高度な使用法にはマルチテーブル結合と複雑なクエリが含まれます。 4)SQL構文エラーやパフォーマンスの問題などのよくある質問は、説明コマンドとスロークエリログを介してデバッグできます。 5)パフォーマンス最適化方法には、インデックスの合理的な使用、最適化されたクエリ、およびキャッシュの使用が含まれます。ベストプラクティスには、トランザクションと準備された星の使用が含まれます ![]() MySQLは、そのパフォーマンス、信頼性、使いやすさ、コミュニティサポートに選択されています。 1.MYSQLは、複数のデータ型と高度なクエリ操作をサポートし、効率的なデータストレージおよび検索機能を提供します。 2.クライアントサーバーアーキテクチャと複数のストレージエンジンを採用して、トランザクションとクエリの最適化をサポートします。 3.使いやすく、さまざまなオペレーティングシステムとプログラミング言語をサポートしています。 4.強力なコミュニティサポートを提供し、豊富なリソースとソリューションを提供します。 ![]() Apacheはデータベースに接続するには、次の手順が必要です。データベースドライバーをインストールします。 web.xmlファイルを構成して、接続プールを作成します。 JDBCデータソースを作成し、接続設定を指定します。 JDBC APIを使用して、接続の取得、ステートメントの作成、バインディングパラメーター、クエリまたは更新の実行、結果の処理など、Javaコードのデータベースにアクセスします。 ![]() DockerでMySQLを起動するプロセスは、次の手順で構成されています。MySQLイメージをプルしてコンテナを作成および起動し、ルートユーザーパスワードを設定し、ポート検証接続をマップしてデータベースを作成し、ユーザーはすべての権限をデータベースに付与します。 ![]() CentOSにMySQLをインストールするには、次の手順が含まれます。適切なMySQL Yumソースの追加。 yumを実行して、mysql-serverコマンドをインストールして、mysqlサーバーをインストールします。ルートユーザーパスワードの設定など、MySQL_SECURE_INSTALLATIONコマンドを使用して、セキュリティ設定を作成します。必要に応じてMySQL構成ファイルをカスタマイズします。 MySQLパラメーターを調整し、パフォーマンスのためにデータベースを最適化します。 ![]() WebアプリケーションにおけるMySQLの主な役割は、データを保存および管理することです。 1.MYSQLは、ユーザー情報、製品カタログ、トランザクションレコード、その他のデータを効率的に処理します。 2。SQLクエリを介して、開発者はデータベースから情報を抽出して動的なコンテンツを生成できます。 3.MYSQLは、クライアントサーバーモデルに基づいて機能し、許容可能なクエリ速度を確保します。 ![]() |