mysql的in数量太多?mysql 大量in解决
- 前端设计
- 2023-08-13
- 122
老铁们,大家好,相信还有很多朋友对于mysql的in数量太多和mysql 大量in解决的相关问题不太懂,没关系,今天就由我来为大家分享分享mysql的in数量太多以及m...
老铁们,大家好,相信还有很多朋友对于mysql的in数量太多和mysql 大量in解决的相关问题不太懂,没关系,今天就由我来为大家分享分享mysql的in数量太多以及mysql 大量in解决的问题,文章篇幅可能偏长,希望可以帮助到大家,下面一起来看看吧!
mysql的中文全文搜索,关于分词,有没有好的解决方案
全文检索在MySQL里面很早就支持了,只不过一直以来只支持英文。缘由是他从来都使用空格来作为分词的分隔符,而对于中文来讲,显然用空格就不合适,需要针对中文语义进行分词。
这不,从MySQL5.7开始,MySQL内置了ngram全文检索插件,用来支持中文分词,并且对MyISAM和InnoDB引擎有效。
在使用中文检索分词插件ngram之前,先得在MySQL配置文件里面设置他的分词大小,比如,[mysqld]ngram_token_size=2这里把分词大小设置为2。要记住,分词的SIZE越大,索引的体积就越大,所以要根据自身情况来设置合适的大小。示例表结构:
CREATETABLEarticles(idINTUNSIGNEDAUTO_INCREMENTNOTNULLPRIMARYKEY,titleVARCHAR(200),bodyTEXT,FULLTEXT(title,body)WITHPARSERngram)ENGINE=InnoDBCHARACTERSETutf8mb4;示例数据,有6行记录。mysql>select*fromarticles\G**************************
*1.row***************************id:1title:数据库管理body:在本教程中我将向你展示如何管理数据库***************************2.row***************************id:2title:数据库应用开发body:学习开发数据库应用程序***************************3.row***************************id:3title:MySQL完全手册body:学习MySQL的一切***************************4.row***************************id:4title:数据库与事务处理body:系统的学习数据库的事务概论***************************5.row***************************id:5title:NoSQL精髓body:学习了解各种非结构化数据库***************************6.row***************************id:6title:SQL语言详解body:详细了解如果使用各种SQL6rowsinset(0.00sec)显式指定全文检索表源mysql>SETGLOBALinnodb_ft_aux_table="new_feature/articles";QueryOK,0rowsaffected(0.00sec)通过系统表,就可以查看到底是怎么划分articles里的数据。
mysql>SELECT*FROMinformation_schema.INNODB_FT_INDEX_CACHELIMIT20,10;+------+--------------+-------------+-----------+--------+----------+|WORD|FIRST_DOC_ID|LAST_DOC_ID|DOC_COUNT|DOC_ID|POSITION|+------+--------------+-------------+-----------+--------+----------+|中我|2|2|1|2|28||习m|4|4|1|4|21||习了|6|6|1|6|16||习开|3|3|1|3|25||习数|5|5|1|5|37||了解|6|7|2|6|19||了解|6|7|2|7|23||事务|5|5|1|5|12||事务|5|5|1|5|40||何管|2|2|1|2|52|+------+--------------+-------------+-----------+--------+----------+10rowsinset(0.00sec)这里可以看到,把分词长度设置为2,所有的数据都只有两个一组。上面数据还包含了行的位置,ID等等信息。
接下来,我来进行一系列检索示范,使用方法和原来英文检索一致。1.自然语言模式下检索:A,得到符合条件的个数,mysql>SELECTCOUNT(*)FROMarticles->WHEREMATCH(title,body)AGAINST('数据库'INNATURALLANGUAGEMODE);+----------+|COUNT(*)|+----------+|4|+----------+1rowinset(0.05sec)B,得到匹配的比率,mysql>SELECTid,MATCH(title,body)AGAINST('数据库'INNATURALLANGUAGEMODE)ASscoreFROMarticles;+----+----------------------+|id|score|+----+----------------------+|1|0.12403252720832825||2|0.12403252720832825||3|0||4|0.12403252720832825||5|0.062016263604164124||6|0|+----+----------------------+6rowsinset(0.00sec)2.布尔模式下搜索,这个就相对于自然模式搜索来的复杂些:A,匹配既有管理又有数据库的记录,mysql>SELECT*FROMarticlesWHEREMATCH(title,body)->AGAINST('+数据库+管理'INBOOLEANMODE);+----+------------+--------------------------------------+|id|title|body|+----+------------+--------------------------------------+|1|数据库管理|在本教程中我将向你展示如何管理数据库|+----+------------+--------------------------------------+1rowinset(0.00sec)B,匹配有数据库,但是没有管理的记录,mysql>SELECT*FROMarticlesWHEREMATCH(title,body)->AGAINST('+数据库-管理'INBOOLEANMODE);+----+------------------+----------------------------+|id|title|body|+----+------------------+----------------------------+|2|数据库应用开发|学习开发数据库应用程序||4|数据库与事务处理|系统的学习数据库的事务概论||5|NoSQL精髓|学习了解各种非结构化数据库|+----+------------------+----------------------------+3rowsinset(0.00sec)C,匹配MySQL,但是把数据库的相关性降低,mysql>SELECT*FROMarticlesWHEREMATCH(title,body)->AGAINST('>数据库+MySQL'INBOOLEANMODE);+----+---------------+-----------------+|id|title|body|+----+---------------+-----------------+|3|MySQL完全手册|学习MySQL的一切|+----+---------------+-----------------+1rowinset(0.00sec)3,查询扩展模式,比如要搜索数据库,那么MySQL,oracle,DB2也都将会被搜索到,mysql>SELECT*FROMarticles->WHEREMATCH(title,body)->AGAINST('数据库'WITHQUERYEXPANSION);+----+------------------+--------------------------------------+|id|title|body|+----+------------------+--------------------------------------+|1|数据库管理|在本教程中我将向你展示如何管理数据库|4|数据库与事务处理|系统的学习数据库的事务概论|2|数据库应用开发|学习开发数据库应用程序||5|NoSQL精髓|学习了解各种非结构化数据库||6|SQL语言详解|详细了解如果使用各种SQL||3|MySQL完全手册|学习MySQL的一切|+----+------------------+--------------------------------------+6rowsinset(0.01sec)当然,我这里只是功能演示,更多的性能测试,大家有兴趣可以进行详细测试。由于N-grm是中文检索常用的分词算法,已经在互联网大量使用,这次集成到mysql中,想必效果上不会有太大的问题。
怎么修改mysql的my.inl
在mysql文件下找到ini,右键选择记事本方式打开,然后找到你要修改的内容,修改后保存即可
mysql数据库binlog是否可能会读取脏数据
之前有做过一个binlog压缩能节约多少空间的测试,效果上看还是比较理想的,可以节约一半以上的空间。但是这个又引出了一个新的问题,那就是这个功能对性能有多大影响呢?于是我又在测试环境试了一下,测试环境的物理配置如下。
根据之前的经验这套测试环境在120个表+240个并发的情况,可以取得一个性能上的极大值;所以在这里就直接使用这个作为测试压力。
8.0.19场景第一步:安装。
dbma-cli-single-instance--port=3306--max-mem=131072\--pkg=mysql-8.0.19-linux-glibc2.12-x86_64.tar.xzinstall
第二步:创建测试用户。
createusersysbench@'%'identifiedby'sysbench';createdatabasetempdb;grantallontempdb.*tosysbench@'%';
第三步:填充数据并进行压力测试。
sysbench--mysql-host=192.168.100.10--mysql-port=3306--mysql-user=sysbench\--mysql-password=sysbench--tables=120--table_size=100000--mysql-db=tempdb\--time=3600--threads=240oltp_point_selectpreparesysbench--mysql-host=192.168.100.10--mysql-port=3306--mysql-user=sysbench\--mysql-password=sysbench--tables=120--table_size=100000--mysql-db=tempdb\--time=3600--threads=240oltp_point_selectrun
性能表现。
资源消耗情况。
8.0.20+binlog压缩第一步:安装。
dbma-cli-single-instance--port=3306--max-mem=131072\--pkg=mysql-8.0.20-linux-glibc2.12-x86_64.tar.xzinstall
第二步:创建测试用户。
createusersysbench@'%'identifiedby'sysbench';createdatabasetempdb;grantallontempdb.*tosysbench@'%';--dbm-agent默认会开启binlog压缩showglobalvariableslike'binlog_transaction_compression%';+-------------------------------------------+-------+|Variable_name|Value|+-------------------------------------------+-------+|binlog_transaction_compression|ON||binlog_transaction_compression_level_zstd|3|+-------------------------------------------+-------+2rowsinset(0.00sec)
第三步:填充数据并进行压力测试。
sysbench--mysql-host=192.168.100.10--mysql-port=3306--mysql-user=sysbench\--mysql-password=sysbench--tables=120--table_size=100000--mysql-db=tempdb\--time=3600--threads=240oltp_point_selectpreparesysbench--mysql-host=192.168.100.10--mysql-port=3306--mysql-user=sysbench\--mysql-password=sysbench--tables=120--table_size=100000--mysql-db=tempdb\--time=3600--threads=240oltp_point_selectrun
性能表现。
资源消耗情况。
8.0.20+binlog不压缩
第一步:关闭binlog压缩功能。
set@@global.binlog_transaction_compression='OFF';showglobalvariableslike'binlog_transaction_compression%';+-------------------------------------------+-------+|Variable_name|Value|+-------------------------------------------+-------+|binlog_transaction_compression|OFF||binlog_transaction_compression_level_zstd|3|+-------------------------------------------+-------+2rowsinset(0.01sec)
第二步:进行压力测试。
sysbench--mysql-host=192.168.100.10--mysql-port=3306--mysql-user=sysbench\--mysql-password=sysbench--tables=120--table_size=100000--mysql-db=tempdb\--time=3600--threads=240oltp_point_selectrun
性能表现。
资源消耗情况。
结论开启binlog压缩会对性能有影响,大概会让性能下降1%,cpu多消耗1%。
mysql查询in为什么用不上索引
1.mysql查询in用不上索引,说明查询语句本身有问题。
2.MySQL是查询语句,最好用Access2010来操作。
3.查询是用来操作数据库中的记录对象,利用它可以按照预先定义的不同条件从数据表或其它查询中筛选出需要操作的字段,并可以把它们集中起来,形成动态数据集。用户可以浏览、查询、打印,甚至修改这个动态数据集中的数据。
4.通过查询,可以查找和检索满足指定条件的数据,包括几个表中的数据,也可以使用查询同时更新或删除几个记录,以及对数据执行预定义或自定义的计算。
5.使用查询可以回答有关数据的特定问题,而这些问题通过表很难解决。可以使用查询筛选数据、执行数据计算和汇总数据。可以使用查询自动执行许多数据管理任务,并在提交数据更改之前查看这些更改。
6.查询实际上也就是选取记录的条件。查询出来的数据也存储到一个临时的表中。用于从表中检索数据或者进行计算的查询称为选择查询,用于添加、更改或删除的查询叫做操作查询。
mysql补齐缺省数据
你给的信息太少,我给你举例吧,假设下表B,是这样的(--只是为了格式):
idclass_idclassinfo
1-----1------明星。。。。。
2---------------军事。。。。。
3------3-----------------。。。。。
4--------------------------高考分数
类别表C
class_idclass
1----明星
2-----军事
3-----体育
4-----高考
比如上面这样的一个情况,你需要补齐类别信息,class_id或者class信息。
一、首先,使用select统计缺失情况。
统计class_id缺失的有多少:selectcount(*)frombwhereclass_idisnullorclass_id=''andclassisnotnull;
统计class缺失的有多少:selectcount(*)frombwhereclassisnullorclass_id=''andclass_idisnotnull;
在正式更新之前,建议,先备份一次,或者创建一张复制表。
createtableb_testselect*fromb;数据太大,就换一种方式:
createtableb_testselect*frombwhere1=2;这样就只创建一张表结构,没有数据,
装载数据:
insertintob_testselect*frombwhereid<20000;
依次类推,直到装载完毕。千万不要直接在原表上直接更新。
如果统计的数量较多,例如超过10w,请分批执行。
补齐class:updateb_test,csetb_test.class=c.classwhereb_test.class_id=c.class_idandb_test.idin(selectidfromb_testwhereclassisnullorclass_id=''andclass_idisnotnulllimit0,20000);
每次只会2w行的更新,多次执行上面SQL语句,对应修改b_test.idin(selectidfromb_testwhereclassisnullorclass_id=''andclass_idisnotnulllimit20000,40000);
依次类推。
补齐class_id:其实也一样:
updateb_test,csetb_test.class_id=c.class_idwhereb_test.class=c.classandb_test.idin(selectidfromb_testwhereclassisnullorclass_id=''andslass_idisnotnulllimit0,20000;
使用统计的SQL,确认一次,是否还有没有修改到的。
最后剩下,class和class_id都没有的,
你可能只有手动处理了。或者
updateb_testsetb_test.id=4,b_test.class='高考'whereinfolike'%高考%';
希望能帮助你解决问题。有任何问题,欢迎私信我。
mysql中怎样对大批量级的数据查询进行优化
MySQL一直以来都支持正则匹配,不过对于正则替换则一直到MySQL8.0才支持。对于这类场景,以前要么在MySQL端处理,要么把数据拿出来在应用端处理。
比如我想把表y1的列str1的出现第3个action的子串替换成dble,怎么实现?
1.自己写SQL层的存储函数。代码如下写死了3个,没有优化,仅仅作为演示,MySQL里非常不建议写这样的函数。
mysql
DELIMITER$$
USE`ytt`$$
DROPFUNCTIONIFEXISTS`func_instr_simple_ytt`$$
CREATEDEFINER=`root`@`localhost`FUNCTION`func_instr_simple_ytt`(
f_strVARCHAR(1000),--Parameter1
f_substrVARCHAR(100),--Parameter2
f_replace_strvarchar(100),
f_timesint--timescounter.onlysupport3.
)RETURNSvarchar(1000)
BEGIN
declarev_resultvarchar(1000)default'ytt';--result.
declarev_substr_lenintdefault0;--searchstringlength.
setf_times=3;--onlysupport3.
setv_substr_len=length(f_substr);
selectinstr(f_str,f_substr)into@p1;--Firstrealposition.
selectinstr(substr(f_str,@p1+v_substr_len),f_substr)into@p2;Secondaryvirtualposition.
selectinstr(substr(f_str,@p2+@p1+2*v_substr_len-1),f_substr)into@p3;--Thirdvirtualposition.
if@p1>0&&@p2>0&&@p3>0then--Fine.
select
concat(substr(f_str,1,@p1+@p2+@p3+(f_times-1)*v_substr_len-f_times)
,f_replace_str,
substr(f_str,@p1+@p2+@p3+f_times*v_substr_len-2))intov_result;
else
setv_result=f_str;--Neverchanged.
endif;
--Purgeallsessionvariables.
set@p1=null;
set@p2=null;
set@p3=null;
returnv_result;
end;
$$
DELIMITER;
--调用函数来更新:
mysql>updatey1setstr1=func_instr_simple_ytt(str1,'action','dble',3);
QueryOK,20rowsaffected(0.12sec)
Rowsmatched:20Changed:20Warnings:0
2.导出来用sed之类的工具替换掉在导入,步骤如下:(推荐使用)1)导出表y1的记录。
mysqlmysql>select*fromy1intooutfile'/var/lib/mysql-files/y1.csv';QueryOK,20rowsaffected(0.00sec)
2)用sed替换导出来的数据。
shellroot@ytt-Aspire-V5-471G:/var/lib/mysql-files#sed-i's/action/dble/3'y1.csv
3)再次导入处理好的数据,完成。
mysql
mysql>truncatey1;
QueryOK,0rowsaffected(0.99sec)
mysql>loaddatainfile'/var/lib/mysql-files/y1.csv'intotabley1;
QueryOK,20rowsaffected(0.14sec)
Records:20Deleted:0Skipped:0Warnings:0
以上两种还是推荐导出来处理好了再重新导入,性能来的高些,而且还不用自己费劲写函数代码。那MySQL8.0对于以上的场景实现就非常简单了,一个函数就搞定了。
mysqlmysql>updatey1setstr1=regexp_replace(str1,'action','dble',1,3);QueryOK,20rowsaffected(0.13sec)Rowsmatched:20Changed:20Warnings:0
还有一个regexp_instr也非常有用,特别是这种特指出现第几次的场景。比如定义SESSION变量@a。
mysqlmysql>set@a='aabbcceefilucy111bs234523556119101020301040';QueryOK,0rowsaffected(0.04sec)
拿到至少两次的数字出现的第二次子串的位置。
mysqlmysql>selectregexp_instr(@a,'[:digit:]{2,}',1,2);+--------------------------------------+|regexp_instr(@a,'[:digit:]{2,}',1,2)|+--------------------------------------+|50|+--------------------------------------+1rowinset(0.00sec)
那我们在看看对多字节字符支持如何。
mysql
mysql>set@a='中国美国俄罗斯日本中国北京上海深圳广州北京上海武汉东莞北京青岛北京';
QueryOK,0rowsaffected(0.00sec)
mysql>selectregexp_instr(@a,'北京',1,1);
+-------------------------------+
|regexp_instr(@a,'北京',1,1)|
+-------------------------------+
|17|
+-------------------------------+
1rowinset(0.00sec)
mysql>selectregexp_instr(@a,'北京',1,2);
+-------------------------------+
|regexp_instr(@a,'北京',1,2)|
+-------------------------------+
|29|
+-------------------------------+
1rowinset(0.00sec)
mysql>selectregexp_instr(@a,'北京',1,3);
+-------------------------------+
|regexp_instr(@a,'北京',1,3)|
+-------------------------------+
|41|
+-------------------------------+
1rowinset(0.00sec)
那总结下,这里我提到了MySQL8.0的两个最有用的正则匹配函数regexp_replace和regexp_instr。针对以前类似的场景算是有一个完美的解决方案。
mysql的in数量太多的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于mysql 大量in解决、mysql的in数量太多的信息别忘了在本站进行查找哦。
本文链接:http://www.xinin56.com/qianduan/2289.html