另类高效模糊检索之按时间片划区段分区检索

MySQL数据库范围、模糊、时间范围(时间段)查询语句 MySQL数据库范围、模糊、时间范围查询语句 My Environment MySQL5.46 1. 模糊查询语句 SELECT 字段 FROM TABLENAME WHERE 某字段 Like 条件 其中条件有四种匹配方式: 1、%:表示任意0个或多个字符。可匹配任意类型和长度的字符,如果是中文,使用两个百分号(%%)来表示。 eg:SELECT * FROM TABLENAME WHERE NAME LIKE ‘%aa%’ 功能:找出NAME中含有aa的所有记录 eg:SELECT * FROM 阅读详情

     最近在做一个项目时遇到从数据集合中根据记录ID检索单个数据的问题,本来是采用for循环顺序查找的方式,但是发现如果数据集合比较大时效率就成了问题,本来也想过采用二分查找方式,后来经过仔细研究并结合数据特点(数据特点:id采用的是YYYYMMDD+10为随机数,addtime为数据添加实时时间,因此id与addtime中的YYYYMMDD肯定相等,不相等的几率几乎不存在),决定采用自主设计的按时间片划区段分区搜索的算法。主要思想就是:

 

    1.数据集按addtime降序排列。

    2.搜索时间范围是根据id得到YYYY-MM-DD,在这一天的0-24小时内添加的数据集内检索。

    3.设定单次搜索块的最大数,即block。   

 

    采用此思想搜索的效率比较:1<循环次数<=日添加数据量+数据集总数/block - 日添加数据量/block,如某数据集总数为1000,数据集尾部最后一天添加的数据量为20,单次搜索块为10,如此时检索的是最后一条数据,则循环次数为1000/10 - 20/10 +20=28次,而采用for循环的顺序查找循环次数则是1000;此处无法采用二分查找法,因为排序字段不是id,如采用二分查找法则需要根据字段id重新排序后查找,而排序耗费的资源也是很大的,在此处也不是理想的算法。此处可以根据日数据量设定block来提高检索效率,对于中小量的数据来说次此算法应该足以应付,大量及海量数据有待进一步研究。

          

            //获取数据集

            public static ObjectTable<Documentcontent> GetCollection(string _DocumentID)

            

            /// <summary>
            /// 获取内容
            /// </summary>
            /// <param name="_DocumentID">文档ID</param>
            /// <returns></returns>
            public static ObjectTable<Documentcontent> GetCollection(string _DocumentID)
            {
                string workSpaceID = Common.GetEditWorkSpaceID();

                //提供跨工作区调用数据源支持
                //workSpaceID = SiteHelper.GetObject.GetItem(workSpaceID).Datasource.Value;

                if (Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.内容_Content]))
                {
                    if (!TestHashTableKey("DocumentContent" + workSpaceID + _DocumentID))
                    {
                        Cache(_DocumentID);
                    }

                    return (ObjectTable<Documentcontent>)hashTableCache["DocumentContent" + workSpaceID + _DocumentID];
                }
                else
                {
                    try
                    {
                        IDocumentcontentDAO dao = DAOManager.Default.GetDAO<IDocumentcontentDAO>();

                        QueryFilter filter = new QueryFilter();

                        if (!isShowDisabled)
                        {
                            filter.Items.Add(new DBField("status", DataType.String, DBOperator.Equal, "0"));
                        }

                        filter.Items.Add(new DBField("documentid", DataType.String, DBOperator.Equal, _DocumentID));

                        using (IDBSession session = DBSessionManager.Default.GetSession(Common.GetEditWorkSpaceDBConnName()))
                        {
                            return dao.SelectList(session, "*", filter, "addtime desc");
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }

 

            //根据记录id在数据集中查找数据

            public static Documentcontent GetItem(string _DocumentID, string _DocumentContentID)

          

            /// <summary>
            /// 根据内容ID获取一个内容
            /// </summary>
            /// <param name="_DocumentContentID">内容ID</param>
            /// <param name="_DocumentID">文档ID</param>
            /// <returns></returns>
            public static Documentcontent GetItem(string _DocumentID, string _DocumentContentID)
            {
                Documentcontent item = null;

                ObjectTable<Documentcontent> lists = GetCollection(_DocumentID);

                //如果记录总数大于10则启用模糊查找
                if (lists.Count >= 10)
                {
                    #region 模糊搜索

                    DateTime _datetime = Convert.ToDateTime(_DocumentContentID.Substring(0, 8).Insert(4, "/").Insert(7, "/"));

                    int sum = lists.Count;

                    //分块大小
                    int block = 10;

                    //分块数
                    int pos = sum / block;

                    //不完整分块
                    int res = sum - pos * block;

                    //搜索分块次数
                    int scount = 0;

                    TimeSpan s_timespan = _datetime.AddDays(1) - lists[0].Addtime.Value;

                    TimeSpan e_timespan = _datetime.AddDays(1) - lists[sum - 1].Addtime.Value;

                    if ((s_timespan.Days > 0) || (e_timespan.Days < 0))//超出列表时间界限
                    {
                        item = null;
                    }
                    else//未超出列表时间界限
                    {
                        for (int i = 0; i < pos; i++)
                        {
                            //scount=0:第一次进入分块查询
                            //scount=1:第二次以上进入查询且当前块的尾部时间<=_datetime
                            //scount=2:退出查询
                            if (scount == 0 || scount == 1)
                            {
                                //lists[(i + 1) * block - 1].Addtime.Value <= _datetime.AddDays(1):当前分块尾部时间大于等于_datetime.AddDays(1)  
                                if ((lists[(i + 1) * block - 1].Addtime.Value <= _datetime.AddDays(1)))
                                {
                                    for (int j = 0; j < block; j++)
                                    {
                                        if (lists[i * block + j].ID.Value == _DocumentContentID)
                                        {
                                            item = lists[i * block + j];

                                            break;
                                        }
                                    }

                                    //在当前分块中未查找到,进入下一分块继续查找,因为当前分块时间点可能在0点到23点59分之间,而_datetime为0点时间,估紧邻的两个分块都有可能是目标搜索块
                                    if (item == null)
                                    {
                                        if (lists[(i + 1) * block - 1].Addtime.Value > _datetime.AddDays(1) && scount == 1)
                                        {
                                            //标示当前块尾部时间已经大于_datetime.AddDays(1),不属于当天的记录,不必再进入下一分块查询
                                            scount = 2;
                                        }
                                        else
                                        {
                                            //进入下一分块查询
                                            scount = 1;
                                        }

                                        continue;
                                    }
                                    else//在当前分块中已经找到,直接退出查找
                                    {
                                        break;
                                    }
                                }
                                else//前一分块时间小于_datetime.AddDays(1)
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                //scount=2:在当前分块中未查找到,且当前分开尾部时间已经小于_datetime.AddDays(1),直接退出查找
                                break;
                            }
                        }

                        //未查到、不完整分块不为零且当前分块尾部时间已经>=_datetime.AddDays(1)
                        if (item == null && res != 0 && scount != 2)
                        {
                            for (int i = pos * block; i < sum; i++)
                            {
                                if (lists[i].ID.Value == _DocumentContentID)
                                {
                                    item = lists[i];

                                    break;
                                }
                            }
                        }
                    }

                    #endregion
                }
                else
                {
                    #region 顺序查找

                    for (int i = 0; i < lists.Count; i++)
                    {
                        if (lists[i].ID.Value == _DocumentContentID)
                        {
                            item = lists[i];

                            break;
                        }
                    }

                    #endregion
                }

                return item;
            }

5个4000比特大状态置换算法的设计与分析 下面是 5 个概念性、实验性的 4000 位可逆置换设计。它们都保证是双射,但未经过密码分析,不可直接用于生产系统。风格分别覆盖:三维 SPN、Feistel、可逆元胞自动机、ARX、宽轨迹/Keccak 式结构。 这 5 个设计分别代表了 SPN、Feistel、元胞自动机、ARX、宽轨迹 Keccak 五种不同风格,覆盖了主流大状态置换的构造思路。再次强调:它们只是实验性概念,若要用于实际协议,必须经过严格安全性分析。 阅读详情

相关推荐

fastjson1.2.83反序列化漏洞

【代码】fastjson1.2.83反序列化漏洞。

Coder的博客 1万+

根据时间字段,查询指定时间段的数据

在日常的SQL查询时,难免会遇到一些求时间段内的数据问题,那我现在就带大家来感受一些常见的一些时间段的数据查询。

2301_76846839的博客 7157

Flutter模块打包AAR集成Android原生项目实践

跨平台开发框架Flutter通过将UI组件渲染为原生代码实现高性能表现,其核心优势在于一套代码可同时运行在iOS和Android平台。在工程实践中,将Flutter模块打包为AAR(Android Archive)进行集成,成为混合开发的主流方案。这种方案既保留了原生项目的稳定性,又能渐进式引入Flutter的高效开发特性。通过配置MethodChannel实现原生与Dart代码通信,开发者可以灵活控制Flutter引擎生命周期,优化内存占用和渲染性能。对于电商、社交等需要快速迭代的业务场景,该方案能显著提

weixin_34025051的博客 399

查询某时间段的数据

文献种类:专题技术总结文献 开发工具与关键技术: vs后端技术 作者:彭智豪 ;年级:2005 ;撰写时间:2022 年 5 月 28日 文献编号: 归档时间: 年 月 日 查询某时间段的数据 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 开发工具与关键技术: vs后端技术 作者:彭智豪 撰写...

m0_56653135的博客 2578

28、解码清华SSVEP基准数据集:从EEG信号到深度学习模型的实战指南

本文详细解析了清华大学SSVEP基准数据集的处理与深度学习模型构建全流程。从EEG信号预处理、数据维度变换到SSVEP分类模型设计,提供了实战代码示例和关键技巧,帮助读者掌握脑机接口领域的数据处理方法与模型优化策略。

weixin_29029995的博客 176

Plecs电力电子仿真专业教程-第一季 第一节 Plecs简介

Plces 电力电子仿真专业教程系列依托专业的电力电子仿真软件Plecs对各种电力电子常用的拓扑及实际设计的方案进行系统及仿真与软件代码仿真实践。通过对各种电路仿真原理的讲解及专业C语言代码程序的编写,提升学员的系统设计能力,软件编程能力与理论分析能力。

3641

【数据库】【算法】从一串数据中获取符合某个条件的时间区间

算法背景 在项目中,经常要看到这么一个要求:从一组根据时间排列的数据,要求计算出其中满足某个条件的一串数据,求这串数据的开始与结束时间. 比如说,用小米手环采集到一组用户的心率数据,要求算出其中有多长时间用户的心率>100. 比如说,通过Gps定位获取到车辆的行驶数据,按要求速度超过80就算超速,那么在这组数据中,车辆超速了多长时间. 在数据采集非常方便的时代,像以上的场景及...

weixin_30455365的博客 418

SNAP计算哨兵2号的LAI/FVC/FAPAR

SNAP的计算LAI方法是基于PROSAIL模型,集成的模块,很方便。首先要下载SNAP软件,下载步骤见。

所有专家都曾始于新手 2505

根据时间段进行查询(参数为年月日,查询数据库中的年月日时分秒)

/** * 开始时间转换 * * @param startTime * @return */ public String startTime(String startTime) { String times = null; if (StringUtils.isNotEmpty(startTime)) { SimpleDateFormat df = new SimpleDateFormat("y.

m0_52071544的博客 2573

C++ (week6、7):Linux系统编程4:网络

Linux网络:计算机网络概述、TCP协议、Socket编程、IO多路复用机制(select、epoll)、HTTP协议、进程池、线程池、大文件网络传输问题

Edward2022的博客 1430

嵌入式软考必备知识点:嵌入式系统开发中的重要概念和示例代码

在嵌入式软考中,有一些重要的知识点需要掌握,包括嵌入式系统的基本概念、编程语言、实时操作系统和硬件接口等。实时操作系统是一种专门设计用于嵌入式系统的操作系统,可以提供对任务调度、中断处理和资源管理等方面的支持。GPIO(通用输入输出):GPIO是嵌入式系统中常用的硬件接口,用于连接外部设备和嵌入式系统。以上是嵌入式软考中的一些必备知识点,包括嵌入式系统的基本概念、编程语言、实时操作系统和硬件接口。通过配置串口的波特率、数据位数和校验位等参数,可以实现与其他设备的可靠通信。一、嵌入式系统的基本概念。

PixeGO的博客 313

【选择时间段,查询时间区间内指定时间节点的数据】

选择时间段,查询时间区间内指定时间节点的数据

luohefu1的博客 1320

3、利用预训练卷积神经网络进行特征提取

本文介绍了如何使用预训练的卷积神经网络(如VGG16)进行图像特征提取,并将提取的特征存储在HDF5数据集中,以便后续用于机器学习模型的训练。文章详细阐述了特征提取的原理、HDF5数据格式的优势、HDF5DatasetWriter类的实现、特征提取流程的代码实现以及实际应用案例。通过该方法,可以在多种图像数据集上高效构建高精度的分类模型。

z2a3b4c5d的博客 114

时分时间点划入不同区间分类(时间段),统计每个时间段出现次数,Python

把不同的时分时间划入到不同时间段,统计每个时间段出现时间点的次数,比如2112划入到(21,22)这个时间段,同时给(21,22)这个时间段计数为1,如果再出现一个时间点2102,那么2102仍划入到(21,22)时间段,并为(21,22)增加1次计数,变为2。用Python实现一个功能,把一个时间划入到不同的时间范围内,比如2305,把这个时间划入到(23,24)区间内。又比如056,划入(0,1)范围内。时分时间点划入不同区间分类(时间段),统计每个时间段出现次数,Python。......

Zhang Phil 2183

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

mysql 根据时间段进行分区

drop table if exists erp_saleout1; CREATE TABLE `erp_saleout1` ( `id` varchar(32) NOT NULL, `vdef18` varchar(32) DEFAULT NULL, `customername` varchar(100) DEFAULT NULL COMMENT '客户名称', `vbillc...

njfengxue的专栏 721

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

按时间范围查询

1.实体类 @Column(name ="create_date", attrName ="time" ,label ="创建时间",queryType = QueryType.GTE), @Column(name ="create_date", attrName ="createDate" ,label ="创建时间",queryType = QueryType.LTE), pr

qingTongYuan的博客 1027

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

ElasticSearch的超时搜索timout机制

ElasticSearch会在timeout时间范围内,将搜索到的部分数据(也可能全部都搜索到),直接返回给client,而不是等所有都数据搜索到再返回 GET /test/_search { "query": { "match_all": { } }, "timeout": "1s" } 返回结果中是否超时会根据阈值进行判断 ...

user2025的博客 3258

Mycat之数据库分片(时间分片,按月份分片)-yellowcong

取模分片,简单来讲,根据数据库的主键和存储的节点数进行取模操作,然后根据取模的结果,将数据存放到对应的节点中,取模分表,可以将数据均匀的分配到各个库中。实现的步骤:1、创建数据库,2、配置schema.xml文件,3、配置server.xml,4、添加rule.xml。这种方式。 数据库时间分片,有个问题,就比如按照月份分片,我只能分片这一年的数据,如果来年了,我还需要自己手动来创建一个表,然后在做

6261

视频隐私脱敏工程化:CSRT/KCF追踪算法在本地推理中的实现与边界

在短视频内容合规审查中,动态遮挡(Dynamic Masking)是高频且高耗时的环节。传统手动关键帧打码不仅效率低下,且在目标快速移动或遮挡时极易出现遮罩漂移。本文从计算机视觉工程角度,解析基于CSRT与KCF算法的目标追踪方案在视频隐私处理中的技术路径、性能权衡及落地实践。

Mysssone的博客 199

【算法拾光】链表 哈希表|K个一组翻转链表 + 两数之和

K个一组翻转链表需分段反转,借助哑节点与前驱指针维护连接,避免断链;两数之和利用哈希表实现O(1)查找,空间换时间,高效定位目标组合。前者考察链表指针操作,后者聚焦映射关系构建,均为面试高频题。

wuqingyigexiaoba的博客 308

排序算法深度笔记(下):非比较类排序的线性突破与工程边界

排序算法时间复杂度额外空间复杂度稳定性是否基于比较选择排序O(N^2)(O(1))不稳定是冒泡排序O(N^2)(O(1))稳定是插入排序O(N^2)(O(1))稳定是归并排序O(N\log N)(O(N))稳定是快速排序O(N\log N)O(log N)不稳定是堆排序O(N\log N)O(1)不稳定是计数排序(O(N + M))O(M))稳定否基数排序O(N)稳定否桶排序平均O(N) / 最坏O(N^2)

2401_87069538的博客 569

算法日常・每日刷题--<动态规划>42

本题为“不相交的线”,与最长公共子序列问题相似。使用动态规划求解:定义 dp[i][j] 表示 nums1[0:i] 与 nums2[0:j] 的最大不相交连线数。若元素相等,则继承左上值加1;否则取上方或左方最大值。最终返回 dp[m][n],即两数组的最大不相交连线数。时间复杂度 O(mn),空间复杂度 O(mn)。

2503_92261635的博客 20

C语言程序设计题|有序数组插入数字冒泡排序

题目要求将一个数插入有序数组末尾,并用冒泡排序实现整体升序。代码先将输入数存入数组最后位置,再通过双重循环进行冒泡排序,每轮将较大元素向后移动,最终输出11个升序元素。该方法虽时间复杂度为O(n²),但符合题目要求,逻辑清晰,适合初学者理解排序原理。

2301_81429079的博客 748

【算法拾光】模拟|外观数列 + 数青蛙

本文总结两道模拟题解法:外观数列通过迭代统计连续数字个数生成下一项,关键在于处理末尾字符;数青蛙则模拟青蛙叫声“croak”状态转移,维护各阶段青蛙数量,记录最大并发数并确保全部完成。共性在于严格遵循流程、细致处理边界与非法情况,锻炼字符串遍历与状态管理能力。

wuqingyigexiaoba的博客 367

牛客周赛165C题(前后缀性质,递推,排序,枚举)

题目大意:给定长度为 `n` 的数组,选择 `k ∈ [1,n]`,将前 `k` 个元素整体翻转,后面的元素不变。要求操作后的整个数组非递减,统计满足条件的 `k` 的数量。题目链接:https://ac.nowcoder.com/acm/contest/141721/C。时间复杂度:O(nlogn)

2501_94316951的博客 170

【数据结构-3】算法美学之降复杂度

在while循环的循环体内,首先用临时变量保存最后一个位置的数据,再通过for循环把所有元素往后移动一位,最后把tmp中保存的值放到下标为0的位置上去。方法二的思路是:创建新数组,让原数组中后k个数据移动到新数组中前面的位置,让原数组中前numsSize-k个数据移动到新数组中后面的位置,这。这段代码的思路是:三次逆置,第一次逆置前numsSize-k个数据,第二次逆置后k个数据,最后整体逆置。这篇博文分享一道解法不一的算法题,求解过程的目的在于降低算法的时间复杂度,题源力扣。,属于空间换时间的操作。

weixin_44218929的博客 82
上一篇: 凌驾于数据库之上的数据静态缓存技术思考和范例
liveweb
博客等级 码龄18年 0粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值