比较MYSQL和ElasticSearch的全文搜索差距_使用es模糊查询的效率比mysql快多少-程序员宅基地

技术标签: 学习验证类  laravel  elasticsearch  php  mysql  

起源

  • 商城项目需要根据商品标题或者商品详情,进行模糊查询,在数据量较大的时候,MYSQL进行模糊查询就吃力了,需要使用全文搜索工具,例如使用人数较多的Elasticsearch。为直观比较两者的性能区别,进行了这个实验,并记录下来。

实验基础

1:MYSQL5.7版本 产品表,7万条数据
2:elasticsearch6.8版本
3:composer 加载 下面这两个依赖,用于发送请求和连接数据库,操作ES,自己基于guzzle写

  • “guzzlehttp/guzzle”: “^6.5”,
  • “illuminate/database”: “5.8.*”
    4:PHP版本7.4
为啥不用别人写好的ES包?
  • ES不同版本,区别较大,之前使用Laravel框架,构建全文检索,很费劲,看网上前人经验,没找到合适的。应该主要是版本对应不起来。就使用guzzle直接发请求了。

实验相关代码

index.php

<?php
ini_set("display_error", true);
error_reporting(-1);
require dirname(__FILE__,2) . '\pro1\vendor\autoload.php';//composer依赖自动载入
require './function.php';

$capsule = new Illuminate\Database\Capsule\Manager;
// 创建链接
$capsule->addConnection(  [
        'driver'    => 'mysql',
        'host'      => 'localhost',
        'database'  => 'meihui',
        'username'  => 'root',
        'password'  => 'root',
        'charset'   => 'utf8',
        'collation' => 'utf8_general_ci',
        'prefix'    => 'ims_',
    ]);

// 设置全局静态可访问DB
$capsule->setAsGlobal();

use Illuminate\Database\Capsule\Manager as DB;

//获取ES版本
//echo ES::getVersion();

$index_name='goods';//ES索引库名,类型名(ES6只支持一个索引库一个类型)

//用于建立ES索引
$mapping=array(
	'mappings'=>[
		$index_name=>[
			'properties'=>[
				'title'=>[
					'type'=>'text',
					'analyzer'=>'ik_max_word'
				],
				'cover'=>[
					'type'=>'keyword'
				],
				'price'=>[
					'type'=>'double'
				]
			]
		]
	]
);

//建立索引
//ES::newIndex($index_name,$mapping);

//将MYSQL数据插入ES

// ini_set('max_execution_time', '0');
// $obj_list = DB::table('zxsite_shop_goods')
//     ->select('id','title','cover','price')
//     ->orderBy('id')
//     ->chunk(200,function($products)use($index_name){
    
//     		foreach($products as $product){
    
//     			ES::newDocByID($index_name,$product->id,(array)$product);
//     		}
//     		echo 'OK_';
//     });

$keyword='焦点自动烟盒';//查哪几个关键字
$fields=['title'];//查哪几个字段

$start = microtime(true);
var_dump(ES::keywordSearch($index_name,$keyword,$fields,10,$page=1,$analyzer='ik_max_word'));
// $re=DB::table('zxsite_shop_goods')->where('title','like','%焦点自动烟盒%')->select('id','title','cover')->limit(10)->get();
// var_dump($re);
$end = microtime(true);
$time=$end-$start;
echo '执行了'.$time.'秒';


// var_dump(ES::getMapping($index_name));
// ES::deleteIndex($index_name);

function.php

<?php
class ES{
    

	public static $host='http://localhost:9200';
	//获取ES版本
	public static function getVersion(){
    
		try{
    
			$http = new GuzzleHttp\Client;
		    $response = $http->get(self::$host);
			$es=json_decode($response->getBody());
			return 'ElasticSearch版本:'.$es->version->number;
		}catch(\Exception $e){
    
			return '无法连接ES服务器';
		}
	}

	//创建索引
	public static function newIndex($index_name,$mapping){
    
		try{
    
			$http = new GuzzleHttp\Client;
		    $response = $http->put(self::$host.'/'.$index_name,
		    	[GuzzleHttp\RequestOptions::JSON=>$mapping]);
			return json_decode($response->getBody())->acknowledged;
		}catch(\Exception $e){
    
			return '创建索引失败';
		}
	}

	//删除索引
	public static function deleteIndex($index_name){
    
		try{
    
			$http = new GuzzleHttp\Client;
		    $response = $http->delete(self::$host.'/'.$index_name);
			return json_decode($response->getBody())->acknowledged;
		}catch(\Exception $e){
    
			return '删除索引失败';
		}
	}

	//获取映射
	public static function getMapping($index_name){
    
		try{
    
			$http = new GuzzleHttp\Client;
		    $response = $http->get(self::$host.'/'.$index_name.'/_mapping');
			return json_decode($response->getBody());
		}catch(\Exception $e){
    
			return '获取索引失败';
		}
	}

	//添加文档(若已经存在,自动更新)
	public static function newDocByID($index_name,$id,$data){
    
		try{
    
			$http = new GuzzleHttp\Client;
		    $response = $http->put(self::$host.'/'.$index_name.'/'.$index_name.'/'.$id,[GuzzleHttp\RequestOptions::JSON=>$data]);
			return json_decode($response->getBody())->result;
		}catch(\Exception $e){
    
			return '添加文档失败';
		}
	}
	//更新文档
	public static function updateDocByID($index_name,$id,$data){
    
		try{
    
			$http = new GuzzleHttp\Client;
		    $response = $http->put(self::$host.'/'.$index_name.'/'.$index_name.'/'.$id.'/_update',[GuzzleHttp\RequestOptions::JSON=>['doc'=>$data]]);
			return json_decode($response->getBody())->result;
		}catch(\Exception $e){
    
			return '更新文档失败';
		}
	}

	//关键字查询
	public static function keywordSearch($index_name,$keyword,$fields,$size=10,$page=1,$analyzer='ik_max_word'){
    
		$temp=['query'=>[
			'query_string'=>[
				'query'=>$keyword,
				'analyzer'=>$analyzer,
				'fields'=>$fields]
			],
			'size'=>$size,
			'from'=>($page-1)*$size
		];
		try{
    
			$http = new GuzzleHttp\Client;
		    $response = $http->get(self::$host.'/'.$index_name.'/'.$index_name.'/_search',[GuzzleHttp\RequestOptions::JSON=>$temp]);
			return json_decode($response->getBody());
		}catch(\Exception $e){
    
			return '查询文档失败';
		}
	}
}
//创建索引

实验结果

ES 查询,内部4(结果中的took)毫秒,代码中代码段的执行时间10ms左右;
MYSQL查询,内部150毫秒左右,代码中代码段的执行时间180ms左右

七万条数据中查,单从内部查询差异来看对这个结果差异,就30多倍。如果数据量更大,差异应该会更大。MYSQL 的like 全文扫描,是一条数据一条数据校对,而ES是使用直接查索引,拿到结果。

  • mysql内部时间查询: show profiles;
    在这里插入图片描述
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44107914/article/details/105816904

智能推荐

docker搭建私有仓库_docker 私人仓库-程序员宅基地

文章浏览阅读8.7k次,点赞3次,收藏39次。Docker 官方提供了一个搭建私有仓库的镜像 registry ,运行该镜像的容器并且对外暴露5000端口就ok了。_docker 私人仓库

服务器出现python错误:distutils.errors.DistutilsError:_distutils.errors.distutilserror: could not find su-程序员宅基地

文章浏览阅读1.6w次。在服务器上运行python安装包时候出现:distutils.errors.DistutilsError: Could not find suitable distribution for Requirement.parse(‘flake8’)解析google-apputils,找不到合适的分布需求解决方法:pip install google-apputils再次运行安装即可..._distutils.errors.distutilserror: could not find suitable distribution for re

freeRTOS:基于(队列+线程)的日志系统设计_freertos日志-程序员宅基地

文章浏览阅读667次。故障排查与调试:嵌入式系统通常运行在资源有限的环境中,故障排查和调试变得尤为复杂。日志系统可以记录系统在运行过程中的各种操作、状态和事件信息,方便开发人员追踪和定位问题所在。通过分析日志,可以快速找到故障源,并进行相应的修复和调试。系统性能优化:嵌入式系统的资源有限,因此性能优化尤为关键。日志系统可以记录系统运行过程中的性能指标,如任务执行时间、资源利用率等。通过分析这些日志,可以发现系统性能瓶颈,进行性能优化和资源管理,提高系统的响应速度和资源利用效率。_freertos日志

剑指offer的python解_python剑指offer题解-程序员宅基地

文章浏览阅读86次。笔记笔记笔记-待更新二维数组中查找题目在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数思路从最右一列往下查找,效率比直接遍历高代码# -*- coding:utf-8 -*-class Solution:# array 二维列表def Find(self, ..._res=[] for i in b: res.append(min_1(a,i)) tem = np.array(res).min() return t

android:layout_weight="1",Android:LinearLayout布局中Layout_weight的深刻理解-程序员宅基地

文章浏览阅读2.9k次,点赞2次,收藏3次。首先看一下LinearLayout布局中Layout_weight属性的作用:它是用来分配属于空间的一个属性,你可以设置他的权重。很多人不知道剩余空间是个什么概念,下面我先来说说剩余空间。看下面代码:android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_par..._"android:layout_weight=\"1"

jenkins war包_Jenkins在Java web项目CI/CD中的简单应用-程序员宅基地

文章浏览阅读94次。JenkinsJenkins is a self-contained, open source automation server which can be used to automate all sorts of tasks related to building, testing, and delivering or deploying software.主要介绍使用Jenkins..._jenkins构建javaweb应用指定war包名

随便推点

Linux提权中常见命令大全-程序员宅基地

文章浏览阅读99次。在拿到一个 webshell 之后,大家首先会想到去把自己的权限提升到最高,windows 我们会提升到 SYSTEM 权限,而 Linux 我们会提升到 root 权限,拿在进行 Linux 提权的时候我们要进行哪些操作呢?需要了解哪些信息?使用什么样的命令?这些就是本文的重点。关于Linux权限提升,有下面几个步骤:信息收集:尽量收集更多的关于系统的信息。数据分析:通过把收集到的数..._执行提权命令的流量包有哪些内容

【扩散模型】论文精读:VLOGGER: Multimodal Diffusion for Embodied Avatar Synthesis-程序员宅基地

文章浏览阅读3.7k次,点赞19次,收藏20次。我们提出了 VLOGGER,这是一种从一个人的单个输入图像生成音频驱动的人类视频的方法,它建立在最近生成扩散模型的成功之上。我们的方法包括 1) 随机人到 3d 运动扩散模型,以及 2) 一种新颖的基于扩散的架构,该架构通过空间和时间控制来增强文本到图像模型。这支持生成可变长度的高质量视频,通过人脸和身体的高级表示轻松控制。与之前的工作相比,我们的方法不需要对每个人进行训练,不依赖于人脸检测和裁剪,生成完整的图像(而不仅仅是人脸或嘴唇),并考虑广泛的场景(例如可见的躯干或不同的主题身份),这对于正确合成交流_vlogger: multimodal diffusion for embodied avatar synthesis

NAO机器人学习笔记(1)-程序员宅基地

文章浏览阅读936次,点赞4次,收藏6次。1 NAO机器人硬件1.1 红外线 红外线发射角度-60°~+60°,波长940nm.1.2 超声波(声纳) NAO能够探测前方0.25~2.55m内是否有障碍物,探测角度60°,超声波频率为49kHZ.1.3 传感器1.3.1 接触传感器 触摸、按压、划过接触传感器可以出发接触传感器产生电信号,进而完成向机器人输入信息. 头部:前中后三个触摸传感器。 手..._nao机器人原理

DSG-RealSync For Oracle技术浅析-2012版-程序员宅基地

文章浏览阅读218次。前言IT系统经过长时间的运行,其作用越来越大,企业的各项运作都严重依赖于IT系统的正常运行;但由于IT系统越来越复杂、资料量越来越庞大、业务类型也越来越多样化,因此IT人员每天都必需面临着如下问题:如何确保系统的正常运行?如何确保业务的连续性和容灾保障?如何提高容灾系统可用性,分担源主产端的业务压力?如何实现硬件平台的开放、异构架构?RealSync复制系统定..._realsync

git_git.w-程序员宅基地

文章浏览阅读101次。1、环境安装Git最新版下载地址:https://gitforwindows.org/TortoiseGit,Git客户端,32/64位最新版及对应的语言包下载地址:https://tortoisegit.org/download/安装的方法,一直下一步就行,具体做法省略。2、配置 1、首先,请选定一个存放Git项目的目录,这样管理方便. 如:D:\te..._git.w

OnTriggerEnter事件、以及触发碰撞、刚体碰撞研究尝试-程序员宅基地

文章浏览阅读6.9k次,点赞4次,收藏7次。一、触发碰撞和刚体碰撞共性:碰撞双方都需要加碰撞器组件,至少有一个添加了刚体组件rigidbody;异同:触发碰撞需要在 碰撞器勾选is trigger选项,刚体碰撞需要使用物理动力模式(isKinematic 选项不能勾选)二、OnTriggerEnter事件执行特点;OnTriggerEnter事件不是每帧调用的,它是基于RigidBody物理碰撞后调用的,不管事件所在的脚本是..._ontriggerenter