为何页面搜索应避免左模糊和全模糊查询???
前言
在构建高效且可扩展的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;};…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
