为何页面搜索应避免左模糊和全模糊查询???
前言
在构建高效且可扩展的Web应用程序时,数据库查询的性能是影响用户体验的关键因素之一。特别是对于涉及大量数据的页面搜索功能,选择正确的查询方式不仅可以提升应用的速度,还能显著改善用户交互体验。
B-Tree索引与最左前缀匹配特性
1. B-Tree 索引基础
B-Tree(或其变体如B+Tree、B*Tree等)是一种自平衡树形数据结构,广泛应用于关系型数据库系统(RDBMS)中作为索引机制。它支持快速插入、删除和查找操作,同时保证了良好的空间利用率。B-Tree的一个重要特性是最左前缀匹配,这意味着:
-
最左前缀原则:当索引字段由多个部分组成时(例如,复合索引),查询条件必须从最左边的部分开始。如果查询条件不满足这个原则,则该索引可能无法被有效利用。
-
索引扫描效率:由于B-Tree索引是从根节点到叶子节点逐层向下查找,因此它非常适合处理以特定前缀开头的查询(即右模糊查询
LIKE 'keyword%')。然而,对于左模糊查询或全模糊查询,因为需要检查所有可能的路径,所以会退化为全表扫描,极大地降低了查询效率。
2. 复合索引与最左前缀原则
复合索引是由多个字段组成的索引,它可以提高多列组合查询的性能。根据最左前缀原则,复合索引中的每一列都必须按照定义顺序出现在查询条件中,否则索引将不会被完全利用。例如,如果你有一个复合索引 (column1, column2),那么查询条件至少应该包含 column1 的值,才能充分利用此索引。
左模糊与全模糊查询的问题详述
1. 左模糊查询 (LIKE '%keyword')
-
索引失效:左模糊查询要求数据库引擎遍历整个索引树来查找所有可能包含关键词的数据记录,导致索引失去作用,进而使查询变为全表扫描,增加了I/O成本。
-
内存消耗:全表扫描意味着更多的数据页会被加载到内存中,这不仅增加了内存占用,还可能导致缓存污染,影响其他查询的性能。
-
CPU资源浪费:每次执行这样的查询都会产生大量的CPU计算,尤其是在高并发环境下,会对服务器造成较大压力。
2. 全模糊查询 (LIKE '%keyword%')
除了上述左模糊查询的所有问题外,全模糊查询还带来了额外的挑战:
-
中间匹配难度大:对于出现在字符串中间位置的关键词,数据库需要进行更加复杂的字符串处理,进一步降低了查询速度。
-
结果集过大:由于没有明确的边界限制,查询可能会返回过多的结果,增加网络传输量和前端渲染时间。
替代方案与最佳实践
为了提高搜索功能的性能,以下是几种推荐的替代方案及最佳实践:
1. 使用全文搜索引擎
引入Elasticsearch、Solr等专门设计的全文搜索引擎,可以有效解决复杂文本检索的需求。这些工具不仅支持基本的模糊匹配,还提供了以下高级功能:
-
分词器:能够根据语言规则对输入文本进行分割,从而提高匹配准确性。
-
权重评分:基于相关性对搜索结果进行排序,确保最重要或最相关的文档优先展示给用户。
-
近似匹配:允许一定程度上的拼写错误或变形词识别,增强用户体验。
-
实时更新:通过增量索引等方式实现实时数据同步,保持搜索结果的新鲜度。
2. 调整查询策略
尽量使用右模糊查询或其他形式的精确匹配查询,以便充分利用现有索引的优势。此外,考虑以下方法优化查询逻辑:
-
多条件组合:结合其他字段进行组合查询,通过多条件筛选减少结果集规模,降低单个查询的复杂度。
-
范围查询:利用日期、数值等类型字段设置合理的查询范围,进一步缩小搜索空间。
-
预过滤:先用简单的条件过滤出一部分数据,再在其基础上做更细致的模糊匹配,这样可以在不影响最终结果的前提下减少不必要的计算。
3. 预计算与缓存
对于频繁访问但变化不大的数据,可以通过预计算和缓存机制提前生成搜索结果,减轻实时查询的压力:
-
静态内容缓存:对于完全不变的内容,可以直接存储HTML片段或JSON响应,直接返回给客户端,无需再次查询数据库。
-
动态内容缓存:针对变化频率较低的数据,可以设定较短的有效期,在此期间内重复使用相同的查询结果。
-
分布式缓存系统:使用Redis、Memcached等分布式缓存解决方案,不仅可以加速数据读取,还可以分散热点数据的压力,提高系统的整体稳定性。
4. 数据库层面的优化
除了调整应用逻辑外,还可以从数据库内部着手,采取一些优化措施:
-
创建覆盖索引:确保索引包含了查询所需的所有列,使得查询可以直接从索引中获取完整信息,而不需要回表查询。
-
分区表:对于特别大的表,可以根据业务特点对其进行水平或垂直分区,减少每次查询的数据量。
-
定期维护索引:随着数据的增长,索引可能会变得臃肿或碎片化,定期重建或优化索引有助于保持其高效性。
-
选择合适的索引类型:不同类型的索引适用于不同的场景,例如哈希索引适合等值查询,全文索引适合文本检索。了解并选择最适合你需求的索引类型可以大幅提升查询性能。
拓展
1. 查询优化器的作用
现代数据库管理系统通常配备有查询优化器,这是一个复杂的组件,负责分析SQL语句并选择最优的执行计划。理解查询优化器的工作原理可以帮助开发者编写更高效的SQL语句,并通过EXPLAIN等工具查看执行计划,找出潜在的性能瓶颈。
2. 并发控制与锁机制
在高并发环境下,合理地管理事务和锁定机制至关重要。不当的锁使用会导致死锁或长等待现象,严重影响系统性能。学习如何最小化锁争用,例如采用乐观锁或无锁编程技术,可以显著提高数据库的并发处理能力。
3. 数据压缩与存储优化
对于大规模数据集,有效的数据压缩和存储格式优化也是不容忽视的一环。通过选择合适的数据类型、压缩算法和存储引擎,可以在不影响数据完整性的情况下节省大量磁盘空间,并加快数据读取速度。
4. 实时数据分析与流处理
随着大数据时代的到来,越来越多的应用需要支持实时数据分析和流处理。Apache Kafka、Flink、Spark Streaming等框架提供了强大的实时数据处理能力,结合全文搜索引擎,可以实现近乎即时的搜索结果更新。
结语
综上所述,虽然左模糊和全模糊查询看似提供了灵活的搜索选项,但从长远来看,它们往往会给数据库带来不必要的负担。
相关文章:
为何页面搜索应避免左模糊和全模糊查询???
前言 在构建高效且可扩展的Web应用程序时,数据库查询的性能是影响用户体验的关键因素之一。特别是对于涉及大量数据的页面搜索功能,选择正确的查询方式不仅可以提升应用的速度,还能显著改善用户交互体验。 B-Tree索引与最左前缀匹配特性 1…...
AI可信论坛亮点:合合信息分享视觉内容安全技术前沿
前言 在当今科技迅猛发展的时代,人工智能(AI)技术正以前所未有的速度改变着我们的生活与工作方式。作为AI领域的重要盛会,CSIG青年科学家会议AI可信论坛汇聚了众多青年科学家与业界精英,共同探讨AI技术的最新进展、挑…...
在 Mac M2 上安装 PyTorch 并启用 MPS 加速的详细教程与性能对比
1. 安装torch 在官网上可以查看安装教程,Start Locally | PyTorch 作者安装了目前最新的torch版本2.5.1,需要提前安装python3.9及以上版本,作者python版本是python3.11最新版本 使用conda安装torch,在终端进入要安装的环境&…...
生成式人工智能在生产型企业中的应用
生成式人工智能(Generative AI)是指使用人工智能来创建新内容,如文本、图像、音乐、音频和视频等。生成式人工智能在生产型企业中的应用涵盖了内容创作与自动化、数据分析与决策支持、生产流程优化、产品设计与开发、客户服务与沟通、员工培训…...
Linux逻辑卷管理
目录 实验要求 实验操作 1、 为Linux新添加一块SCSI磁盘/dev/sdc,容量为1024MB。在该磁盘上创建三个分区sdc1、sdc2、sdc3,大小为128MB,标识为Linux native分区。 2、 在三个分区上创建物理卷;将三个物理卷加入VolGroup00卷组&…...
机器人加装电主轴【铣削、钻孔、打磨、去毛刺】更高效
机器人加装电主轴进行铣削、钻孔、打磨、去毛刺等作业,展现出显著的优势,并能实现高效加工。 1. 高精度与高效率 电主轴特点:高速电主轴德国SycoTec的产品,转速可达100000rpm,功率范围广,精度≤1μm&#…...
opencv sdk for java中提示无stiching模块接口的问题
1、问题介绍 安卓项目中有新的需求,在 jni 中增加 stiching_detail.cpp 中全景拼接的实现。 但是在编译时,出现大量报错,如下截图所示 实际上,其他opencv的接口函数 例如 core dnn等都能正常使用,直觉上初步怀疑 ope…...
今天最新早上好问候语精选大全,每天问候,相互牵挂,彼此祝福
1、朋友相伴,友谊真诚永不变!彼此扶持绿树荫,共度快乐雨后天!一同分享的表情,愿我们友情长存,一生相伴永相连! 2、人生几十年,苦累伴酸甜,风华不再茂,雄心非当…...
五种IO模型- 阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO
在操作系统中处理输入/输出(IO)操作的过程中,存在多种方式,包括阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO。这些方式在操作系统实现和应用程序编写时有着不同的适用场景和性能特征。接下来,我将逐一介绍它们…...
Vscode GStreamer插件开发环境配置
概述 本教程使用vscode和Docker搭建Gstreamer2.24的开发环境,可以用于开发调试Gstreamer程序或者自定义插件开发。 1. vscode依赖插件 C/C Extension Pack(ms-vscode.cpptools-extension-pack):该插件包包含一组用于 Visual St…...
flask基础
from flask import Flask, requestapp Flask(__name__)# app.route(/) # def hello_world(): # put applications code here # return Hello World!app.route(/) # 路由 当用户访问特定 URL 时,Flask 会调用对应的视图函数来处理请求 def index():return …...
Java日志框架:log4j、log4j2、logback
文章目录 配置文件相关1. properties测试 2. XMl使用Dom4j解析XML Log4j与Log4j2日志门面 一、Log4j1.1 Logges1.2 Appenders1.3 Layouts1.4 使用1.5 配置文件详解1.5.1 配置根目录1.5.2 配置日志信息输出目的地Appender1.5.3 输出格式设置 二、Log4j22.1 XML配置文件解析2.2 使…...
鸿蒙-expandSafeArea使用
应用未使用setWindowLayoutFullScreen()接口设置窗口全屏布局时,默认使能组件安全区布局。可以使用expandSafeArea属性扩展安全区域属性进行调整 扩展安全区域属性原理 布局阶段按照安全区范围大小进行UI元素布局。布局完成后查看设置了expandSafeArea的组件边界&…...
【es6复习笔记】Spread 扩展运算符(8)
在现代前端开发中,JavaScript 的扩展运算符(Spread Operator)是一个非常有用的特性,它允许你将数组或对象展开,以便在函数调用、数组拼接、对象复制等场景中更方便地处理数据。扩展运算符(spread࿰…...
第22天:信息收集-Web应用各语言框架安全组件联动系统数据特征人工分析识别项目
#知识点 1、信息收集-Web应用-开发框架-识别安全 2、信息收集-Web应用-安全组件-特征分析 一、ICO图标: 1、某个应用系统的标示,如若依系统有自己特点的图标;一旦该系统出问题,使用该系统的网站都会受到影响; 2、某个公…...
后端-redis
Redis RedisString类型String类型的常用命令 Hash类型Hash类型的常用命令 List类型List类型的常用命令 Set类型Set类型的常用命令 SortedSet类型SortedSet类型的常用命令 Redis序列化缓存更新策略缓存穿透缓存雪崩缓存击穿 Redis Redis是一个key-value的数据库,key…...
开发场景中Java 集合的最佳选择
在 Java 开发中,集合类是处理数据的核心工具。合理选择集合,不仅可以提高代码效率,还能让代码更简洁。本篇文章将重点探讨 List、Set 和 Map 的适用场景及优缺点,帮助你在实际开发中找到最佳解决方案。 一、List:有序存…...
golangci-lint安装与Goland集成
golangci-lint安装与Goland集成 1.golangci-lint概述2.golangci-lint安装3.Goland 中集成 golangci-lint4.golangci-lint 的使用5.排除代码检查 1.golangci-lint概述 golangci-lint是用于go语言的代码静态检查工具集 官网地址:golangci-lint 特性: 快…...
金仓数据库安装-Kingbase v9-centos
在很多年前有个项目用的金仓数据库,上线稳定后就没在这个项目了,只有公司的开发环境还在维护,已经好多年没有安装过了,重温一下金仓数据库安装,体验一下最新版本,也做一个新版本的试验环境; 一、…...
条款6:auto推导若非己愿,使用显式类型初始化惯用法
一、代理类 所谓的代理类就是以模仿和增强一些类型的行为为目的存在的类 class MyArray { public:class MyArraySize{public:MyArraySize(int size) : theSize(size) {}int size() const { return theSize; }operator int() const { return theSize; }private:int theSize;};…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.
这个警告表明您在使用Vue的esm-bundler构建版本时,未明确定义编译时特性标志。以下是详细解释和解决方案: 问题原因: 该标志是Vue 3.4引入的编译时特性标志,用于控制生产环境下SSR水合不匹配错误的详细报告1使用esm-bundler…...
