mysqlフィートとは何ですか
mysql ft は FullText、つまりフルテキスト インデックスを指します。フルテキスト インデックスは、正確な数値比較ではなく、類似性に基づいてクエリを解決するためのものです。フルテキスト インデックスは N 回作成できます。大量のデータに直面したときよりも速く、速度は桁違いではありません。
このチュートリアルの動作環境: Windows 10 システム、mysql8 バージョン、Dell G3 コンピューター。
mysql ft とは何ですか?
つまり、フルテキスト インデックス (FullText) です。
MySQL フルテキスト インデックス (FullText)
1. はじめに
基本概念
フルテキスト インデックスは次のことを解決します。正確な数値比較ではなく、類似性クエリに基づく必要があります。
あいまい一致は like %
を使用して実現することもできますが、大量のテキスト データの検索では考えられません。大量のデータに直面した場合、全文インデックス作成は like
よりも N 倍高速になる可能性がありますが、その速度は桁違いではありません。
バージョンのサポート
-
MySQL 5.6
以前のバージョンでは、MyISAM
ストレージ エンジンのみがフルテキスト インデックスをサポートしていました -
MySQL 5.6
以降のバージョン、MyISAM
およびInnoDB
ストレージ エンジンはフルテキスト インデックスをサポートします -
MySQL 5.7.6
、中国語、日本語、および韓国語 (CJK) をサポートする組み込みのフルテキストngram パーサー
と、日本語用のインストール可能なMeCab
フルテキスト パーサー プラグインを提供します。 - フルテキスト インデックス
InnoDB
またはMyISAM
テーブルにのみ使用でき、CHAR
、に対してのみ作成できます# VARCHAR
、TEXT
列 ##大規模なデータ セットの場合、フルテキスト インデックスを使用せずにデータをデータベースにロードすると、テーブルにインデックスを作成する方が、既存のフルテキスト インデックスを使用してテーブルにデータをロードするよりもはるかに高速になります - RDS MySQL 5.6
中国語の全文検索もサポートされていますが、バグがあります
- 結果としてディスク リソースが大量に占有されます。フルテキスト インデックス自体は、パフォーマンスのためにディスク領域を使用する方法です。全文インデックスが大きい理由は、特定の言語に従って単語分割が行われるためです。 全文インデックスの作成が遅く、全文インデックスを使用してさまざまなデータの変更操作が行われるためです。インデックスも遅いです。
- フルテキスト インデックスの使用は、アプリケーションに対して透過的ではありません。フルテキスト インデックスを使用する場合は、クエリ ステートメントを変更する必要があります。元のクエリ ステートメントにフルテキスト インデックスを使用することは不可能なので、フルテキスト インデックスで指定された構文に変更する必要があります。
- 大文字と小文字は区別されません
- パーティション化されたテーブルでは、大文字と小文字が区別されません。全文検索のサポート
- By 複数の列で構成される全文検索のインデックスは、同じ文字セットと並べ替え規則を使用する必要があります
- 全文インデックスには精度の問題がある可能性があります、つまり、フルテキスト インデックスで見つかったデータは、 と同じではない可能性があります。
のように
Inconsistency - MATCH() 関数の列は、次とまったく同じである必要があります。 IN BOOLEAN MODE モードでの全文検索が MyISAM テーブルで使用されている場合を除き、FULLTEXT インデックスで定義された列 (作成せずに使用できます。インデックス付きの列は検索されますが、速度が非常に遅くなります)
- フルテキスト インデックスが 1 つの列に対して個別に確立されている場合、複数列のあいまいクエリは有効になりません
- 異なるテーブルのフルテキスト インデックスを一緒にクエリすることはできません。それらは 2 つの追加でクエリできます。 OR
を各ステートメントに適用します。 2. フルテキスト インデックスを操作します。
2.1 最小検索長を設定します。
現在設定されている最小検索長は、次の方法で確認できます。 SQL コマンド (単語セグメントの長さ):
SHOW VARIABLES LIKE 'ft%';
Value | |||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
-><()~*:""&| | |||||||||||||||||||||||||||||||||||||||||||||
84 | |||||||||||||||||||||||||||||||||||||||||||||
1 | |||||||||||||||||||||||||||||||||||||||||||||
20 | |||||||||||||||||||||||||||||||||||||||||||||
(built-で )############ 全文索引的相关参数都无法进行动态修改,必须通过修改 MySQL 的配置文件来完成。修改最小搜索长度的值为 1,首先打开 MySQL 的配置文件 /etc/my.cnf,在 [mysqld] 的下面追加以下内容: [mysqld] innodb_ft_min_token_size = 1 # 最短的索引字符串,默认值为4 ft_min_word_len = 1 ログイン後にコピー 配置完后重启 MySQL 服务器,并修复或重建全文索引方可生效。 repair table test quick; ログイン後にコピー 2.2 创建索引
CREATE TABLE fulltext_test ( id int(11) NOT NULL AUTO_INCREMENT, content TEXT NOT NULL, tag VARCHAR(255), PRIMARY KEY (id), FULLTEXT KEY content_tag_fulltext(content, tag) WITH PARSER ngram ) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; ログイン後にコピー
CREATE FULLTEXT INDEX content_fulltext ON fulltext_test(content) with parser ngram; ログイン後にコピー
ALTER TABLE fulltext_test ADD FULLTEXT INDEX content_fulltext(content) with parser ngram; ログイン後にコピー 2.3 删除索引
DROP INDEX content_fulltext ON fulltext_test; ログイン後にコピー
ALTER TABLE fulltext_test DROP INDEX content_fulltext; ログイン後にコピー 三、检索数据3.1 自然语言的全文检索默认情况下,或者使用 in natural language mode 修饰符时,match() 函数对文本集合执行自然语言搜索。 SELECT * FROM 表名 WHERE Match(列名1,列名2) Against (检索内容1 检索内容2); ログイン後にコピー 检索内容不需要用逗号隔开! 自然语言搜索引擎将计算每一个文档对象和查询的相关度。这里,相关度是基于匹配的关键词的个数,以及关键词在文档中出现的次数。在整个索引中出现次数越少的词语,匹配时的相关度就越高。相反,非常常见的单词将不会被搜索,如果一个词语的在超过 50% 的记录中都出现了,那么自然语言的搜索将不会搜索这类词语。 ログイン後にコピー 3.2 布尔全文检索在布尔搜索中,我们可以在查询中自定义某个被搜索的词语的相关性,当编写一个布尔搜索查询时,可以通过一些前缀修饰符来定制搜索。
+aaa +(>bbb <ccc) aaa="aaa" sql="sql" select="select" from="from" test="test" where="where" match="match" against="against" in="in" boolean="boolean" mode="mode" select="select" from="from" tommy="tommy" where="where" match="match" against="against" in="in" boolean="boolean" mode="mode" select="select" from="from" tommy="tommy" where="where" match="match" against="against">李秀琴 <练习册 <不是人>是个鬼' in boolean mode);<h2 id="四-测试结果">四、测试结果</h2> <p><strong>测试环境</strong>:本机4核16G Windows10,MySQL 8.0<br><strong>测试数据量</strong>:<code>salebilldetail</code> 表 <code>1276</code>万行,<code>salebill</code> 表 <code>269</code> 万行, <code>customer</code> 表 <code>30</code> 万行, <code>goods</code> 表 <code>75</code> 万行。</p> <p>争对测试用的SQL语句,增加了以下全文索引:</p> <pre class="brush:php;toolbar:false">CREATE FULLTEXT INDEX billno_fulltext ON salebill(billno) WITH PARSER ngram; CREATE FULLTEXT INDEX remarks_fulltext ON salebill(remarks) WITH PARSER ngram; CREATE FULLTEXT INDEX remarks_fulltext ON salebilldetail(remarks) WITH PARSER ngram; CREATE FULLTEXT INDEX goodsremarks_fulltext ON salebilldetail(goodsremarks) WITH PARSER ngram; CREATE FULLTEXT INDEX remarks_goodsremarks_fulltext ON salebilldetail(remarks, goodsremarks) WITH PARSER ngram; CREATE FULLTEXT INDEX custname_fulltext ON customer(custname) WITH PARSER ngram; CREATE FULLTEXT INDEX goodsname_fulltext ON goods(goodsname) WITH PARSER ngram; CREATE FULLTEXT INDEX goodscode_fulltext ON goods(goodscode) WITH PARSER ngram; ログイン後にコピー 测试结果,总的来说很魔幻。 test_1-- 测试1,原始 like 查询方式,用时 0.765s select 1 from salebilldetail d where d.tid=260434 and ((d.remarks like concat('%','葡萄','%')) or (d.goodsremarks like concat('%','葡萄','%'))); ログイン後にコピー test_2-- 测试2,使用全文索引 remarks_fulltext、goodsremarks_fulltext, 用时 0.834s select 1 from salebilldetail d where d.tid=260434 and ((match(d.remarks) Against(concat('"','葡萄','"') in boolean mode)) or (match(d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode))); ログイン後にコピー test_3-- 测试3,使用全文索引 remarks_goodsremarks_fulltext, 用时 0.242s select 1 from salebilldetail d where d.tid=260434 and ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode))); ログイン後にコピー test_4-- 测试4,原始 like 查询方式,不过滤 tid ,用时 22.654s select t from salebilldetail d where ((d.remarks like concat('%','葡萄','%')) or (d.goodsremarks like concat('%','葡萄','%'))); ログイン後にコピー test_5-- 测试5,使用全文索引 remarks_fulltext、goodsremarks_fulltext, 不过滤 tid ,用时 24.855s select 1 from salebilldetail d where ((match(d.remarks) Against(concat('"','葡萄','"') in boolean mode)) or (match(d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode))); ログイン後にコピー test_6-- 测试6,使用全文索引 remarks_goodsremarks_fulltext, 不过滤 tid ,用时 0.213s select 1 from salebilldetail d where ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode))); ログイン後にコピー test_7-- 测试7,使用全文索引 remarks_goodsremarks_fulltext, 用时 0.22s select count(1) from salebilldetail d where d.tid=260434 and ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode))); ログイン後にコピー test_8-- 测试8,使用全文索引 remarks_goodsremarks_fulltext, 不过滤 tid ,用时 0.007s select count(1) from salebilldetail d where ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode))); ログイン後にコピー 从上面的测试语句可以看出,数据量越多,查询越简单,全文索引的效果越好。 再来看看我们的业务测试SQL: test_9-- 测试9 select i.billid ,if(0,0,i.qty) as qty ,if(0,0,i.goodstotal) as total ,if(0,0,i.chktotal) as selfchktotal ,if(0,0,i.distotal) as distotal ,if(0,0,i.otherpay) as feetotal ,if(0,0,ifnull(d.costtotal,0)) as costtotal ,if(0,0,ifnull(d.maoli,0)) as maoli ,i.billno ,from_unixtime(i.billdate,'%Y-%m-%d') as billdate /*单据日期*/ ,from_unixtime(i.createdate,'%Y-%m-%d %H:%i:%s') as createdate /*制单日期*/ ,if(i.sdate=0,'',from_unixtime(i.sdate,'%Y-%m-%d %H:%i:%s')) as sdate /*过账日期*/ ,from_unixtime(i.udate,'%Y-%m-%d %H:%i:%s') as udate /*最后修改时间*/ ,i.custid ,c.custname ,i.storeid ,k.storename ,i.empid ,e.empname ,i.userid ,u.username ,i.remarks /*单据备注*/ ,i.effect,i.settle,i.redold,i.rednew /*单据状态*/ ,i.printtimes /* 打印次数 */ ,(case when i.rednew=1 then 1 when i.redold=1 then 2 when i.settle=1 then 3 when i.effect=1 then 4 else 9 end) as state /*单据状态*/ ,(case when i.rednew=1 then '红冲单' when i.redold=1 then '已红冲' when i.settle=1 then '已结算' when i.effect=1 then '已过账' else '草稿' end) as statetext ,'' as susername /* 操作人 */ ,'' as accname /* 科目 */ from salebill i left join coursecentersale d on d.tid=i.tid and d.billid=i.billid left join customer c on c.tid=i.tid and c.custid=i.custid left join store k on k.tid=i.tid and k.storeid=i.storeid left join employee e on e.tid=i.tid and e.empid=i.empid left join user u on u.tid=i.tid and u.userid=i.userid where i.tid=260434 and (i.billtype = 5 or i.effect = 1) and ('_billdate_f_'!='') and ('_billdate_t_'!='') and ('_sdate_f_'!='') and ('_sdate_t_'!='') and ('_udate_f_'!='') and ('_udate_t_'!='') and ('_cdate_f_'!='') and ('_cdate_t_'!='') and ('_billid_'!='') /*单据id*/ and ('_custid_'!='') /*客户ID*/ and ('_storeid_'!='') /*店仓ID*/ and ('_empid_'!='') /*业务员ID*/ and ('_custstop_'!='') /*客户是否停用*/ and ( (i.billno like concat('%','葡萄','%')) or (i.remarks like concat('%','葡萄','%')) or exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((d.remarks like concat('%','葡萄','%')) or (d.goodsremarks like concat('%','葡萄','%')))) or exists(select 1 from customer c where c.tid=260434 and c.custid=i.custid and (c.custname like concat('%','葡萄','%'))) or exists(select 1 from goods g join salebilldetail d on d.tid=g.tid and d.goodsid=g.goodsid where d.tid=260434 and d.billid=i.billid and ((g.goodsname like concat('%','葡萄','%')) or (g.goodscode like concat('%','葡萄','%')))) ) and i.rednew=0 /*单据列表不含红冲单*/ and i.billid not in (select billid from coursecenter_del t where t.tid=260434) and ((i.settle=1 and i.effect=1 and i.redold=0 and i.rednew=0)) /*已结算*/ order by udate desc,billno desc limit 0,100; ログイン後にコピー 执行时间约 改成使用全文索引方式: test_10-- 测试10 select i.billid ,if(0,0,i.qty) as qty ,if(0,0,i.goodstotal) as total ,if(0,0,i.chktotal) as selfchktotal ,if(0,0,i.distotal) as distotal ,if(0,0,i.otherpay) as feetotal ,if(0,0,ifnull(d.costtotal,0)) as costtotal ,if(0,0,ifnull(d.maoli,0)) as maoli ,i.billno ,from_unixtime(i.billdate,'%Y-%m-%d') as billdate /*单据日期*/ ,from_unixtime(i.createdate,'%Y-%m-%d %H:%i:%s') as createdate /*制单日期*/ ,if(i.sdate=0,'',from_unixtime(i.sdate,'%Y-%m-%d %H:%i:%s')) as sdate /*过账日期*/ ,from_unixtime(i.udate,'%Y-%m-%d %H:%i:%s') as udate /*最后修改时间*/ ,i.custid ,c.custname ,i.storeid ,k.storename ,i.empid ,e.empname ,i.userid ,u.username ,i.remarks /*单据备注*/ ,i.effect,i.settle,i.redold,i.rednew /*单据状态*/ ,i.printtimes /* 打印次数 */ ,(case when i.rednew=1 then 1 when i.redold=1 then 2 when i.settle=1 then 3 when i.effect=1 then 4 else 9 end) as state /*单据状态*/ ,(case when i.rednew=1 then '红冲单' when i.redold=1 then '已红冲' when i.settle=1 then '已结算' when i.effect=1 then '已过账' else '草稿' end) as statetext ,'' as susername /* 操作人 */ ,'' as accname /* 科目 */ from salebill i left join coursecentersale d on d.tid=i.tid and d.billid=i.billid left join customer c on c.tid=i.tid and c.custid=i.custid left join store k on k.tid=i.tid and k.storeid=i.storeid left join employee e on e.tid=i.tid and e.empid=i.empid left join user u on u.tid=i.tid and u.userid=i.userid where i.tid=260434 and (i.billtype = 5 or i.effect = 1) and ('_billdate_f_'!='') and ('_billdate_t_'!='') and ('_sdate_f_'!='') and ('_sdate_t_'!='') and ('_udate_f_'!='') and ('_udate_t_'!='') and ('_cdate_f_'!='') and ('_cdate_t_'!='') and ('_billid_'!='') /*单据id*/ and ('_custid_'!='') /*客户ID*/ and ('_storeid_'!='') /*店仓ID*/ and ('_empid_'!='') /*业务员ID*/ and ('_custstop_'!='') /*客户是否停用*/ and ( (match(i.billno) against(concat('"','葡萄','"') in boolean mode)) or (match(i.remarks) against(concat('"','葡萄','"') in boolean mode)) or exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((match(d.remarks) Against(concat('"','葡萄','"') in boolean mode)) or (match(d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode)))) or exists(select 1 from customer c where c.tid=260434 and c.custid=i.custid and (match(c.custname) Against(concat('"','葡萄','"') in boolean mode))) or exists(select 1 from goods g join salebilldetail d on d.tid=g.tid and d.goodsid=g.goodsid where d.tid=260434 and d.billid=i.billid and ((match(g.goodsname) Against(concat('"','葡萄','"') in boolean mode)) or (match(g.goodscode) Against(concat('"','葡萄','"') in boolean mode)))) ) and i.rednew=0 /*单据列表不含红冲单*/ and i.billid not in (select billid from coursecenter_del t where t.tid=260434) and ((i.settle=1 and i.effect=1 and i.redold=0 and i.rednew=0)) /*已结算*/ order by udate desc,billno desc limit 0,100; ログイン後にコピー 执行时间约 最魔幻的地方来了,如果将上面的SQL语句中( exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((match(d.remarks) Against(concat('"','葡萄','"') in boolean mode)) or (match(d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode)))) ログイン後にコピー test_11改成使用全文索引 -- 测试11 exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode)))) ログイン後にコピー 执行时间无限长(跑了半天没成功)? -- and 中只有一个全文检索时正常, 用时0.2秒 select xxx from xxx ... and ( exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode)))) ) ... -- 下面这样就异常了,会慢成百上千倍,用时 160 秒, 如果有更多的 match ,会更夸张的慢下去 select xxx from xxx ... and ( exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode)))) or match(i.billno) against(concat('"','葡萄','"') in boolean mode) ) ... ログイン後にコピー 测试结果汇总:
五、MySQL 版本升级因线上系统目前是 RDS MySQL 5.6,故简单描述升级相关问题。
【相关推荐:mysql视频教程】 |
以上がmysqlフィートとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











Laravelは、Webアプリケーションを簡単に構築するためのPHPフレームワークです。次のような強力な機能を提供します。インストール:Laravel CLIを作曲家にグローバルにインストールし、プロジェクトディレクトリにアプリケーションを作成します。ルーティング:ルート/web.phpのURLとハンドラーの関係を定義します。ビュー:リソース/ビューでビューを作成して、アプリケーションのインターフェイスをレンダリングします。データベース統合:MySQLなどのデータベースとのすぐ外側の統合を提供し、移行を使用してテーブルを作成および変更します。モデルとコントローラー:モデルはデータベースエンティティを表し、コントローラーはHTTP要求を処理します。

MySQLとPHPMyAdminは、強力なデータベース管理ツールです。 1)MySQLは、データベースとテーブルを作成し、DMLおよびSQLクエリを実行するために使用されます。 2)PHPMyAdminは、データベース管理、テーブル構造管理、データ操作、ユーザー許可管理のための直感的なインターフェイスを提供します。

他のプログラミング言語と比較して、MySQLは主にデータの保存と管理に使用されますが、Python、Java、Cなどの他の言語は論理処理とアプリケーション開発に使用されます。 MySQLは、データ管理のニーズに適した高性能、スケーラビリティ、およびクロスプラットフォームサポートで知られていますが、他の言語は、データ分析、エンタープライズアプリケーション、システムプログラミングなどのそれぞれの分野で利点があります。

小さなアプリケーションを開発する際には、軽量データベース操作ライブラリをすばやく統合する必要性という厄介な問題に遭遇しました。複数のライブラリを試した後、私はそれらがあまりにも多くの機能を持っているか、あまり互換性がないかのどちらかであることがわかりました。最終的に、私は問題を完全に解決したYii2に基づいた単純化されたバージョンであるMinii/DBを見つけました。

記事の概要:この記事では、Laravelフレームワークを簡単にインストールする方法について読者をガイドするための詳細なステップバイステップの指示を提供します。 Laravelは、Webアプリケーションの開発プロセスを高速化する強力なPHPフレームワークです。このチュートリアルは、システム要件からデータベースの構成とルーティングの設定までのインストールプロセスをカバーしています。これらの手順に従うことにより、読者はLaravelプロジェクトのための強固な基盤を迅速かつ効率的に築くことができます。

Theliaを使用してeコマースWebサイトを開発するとき、私はトリッキーな問題に遭遇しました:MySQLモードが適切に設定されていないため、いくつかの機能が適切に機能しません。いくつかの調査の後、TheliamysQlModescheckerというモジュールを見つけました。これは、Theliaが必要とするMySQLパターンを自動的に修正できるため、問題を完全に解決できます。

MySQLでは、外部キーの機能は、テーブル間の関係を確立し、データの一貫性と整合性を確保することです。外部キーは、参照整合性チェックとカスケード操作を通じてデータの有効性を維持します。パフォーマンスの最適化に注意し、それらを使用するときに一般的なエラーを避けてください。

MySQLとMariaDBの主な違いは、パフォーマンス、機能、ライセンスです。1。MySQLはOracleによって開発され、Mariadbはフォークです。 2. Mariadbは、高負荷環境でパフォーマンスを向上させる可能性があります。 3.MariaDBは、より多くのストレージエンジンと機能を提供します。 4.MySQLは二重ライセンスを採用し、MariaDBは完全にオープンソースです。既存のインフラストラクチャ、パフォーマンス要件、機能要件、およびライセンスコストを選択する際に考慮する必要があります。
