当前位置: 首页 > wzjs >正文

wordpress电影自动采集主题seo软件视频教程

wordpress电影自动采集主题,seo软件视频教程,工程建设标准网站,穿衣搭配的网站如何做背景 head头表(5000),line行表(15万),导出数据包含头和行,一对多。 以行表为维度导出15万数据。 sql 如下两个sql查询,有如下差异 驱动方式:第一个大表驱动小表&…

背景

head头表(5000),line行表(15万),导出数据包含头和行,一对多。

以行表为维度导出15万数据。

 sql

如下两个sql查询,有如下差异

驱动方式:第一个大表驱动小表,第二个反之

第一个自己比较:根据ID排序,和不排序,explain分析

explainselecthead.code,head.company_code,head.company_name,head.expense_date,head.data_source_num,head.data_source,head.prepared_by,head.status,line.asset_number,line.tag_number,line.asset_name,line.asset_category_1,line.asset_category_2,line.retired_units,line.retired_date,line.retirement_type,line.retirement_cost,line.disposal_amount,line.commentfromasset_fa_disposal_line lineleft join asset_fa_disposal head on line.parent_code = head.codeorder by line.id desclimit 0,1000无排序    SIMPLE	line		ALL					141466	100.0	
1	SIMPLE	head		eq_ref	uniq_code	uniq_code	194	fssc_backend_asset.line.parent_code	1	100.0	有排序
1	SIMPLE	line		index		PRIMARY	8		141466	100.0	Backward index scan
1	SIMPLE	head		eq_ref	uniq_code	uniq_code	194	fssc_backend_asset.line.parent_code	1	100.0	--         asset_fa_disposal head
--         left join asset_fa_disposal_line line on head.code = line.parent_code--   order by line.id descexplainselecthead.code,head.company_code,head.company_name,head.expense_date,head.data_source_num,head.data_source,head.prepared_by,head.status,line.asset_number,line.tag_number,line.asset_name,line.asset_category_1,line.asset_category_2,line.retired_units,line.retired_date,line.retirement_type,line.retirement_cost,line.disposal_amount,line.commentfromasset_fa_disposal headleft join asset_fa_disposal_line line on head.code = line.parent_codeorder by line.id desclimit 0,1000无排序     SIMPLE	head		ALL					4832	100.0	
1	SIMPLE	line		ref	disposal_line_parent_code	disposal_line_parent_code	194	fssc_backend_asset.head.code	31	100.0	有排序
1	SIMPLE	head		ALL					4832	100.0	Using temporary; Using filesort
1	SIMPLE	line		ref	disposal_line_parent_code	disposal_line_parent_code	194	fssc_backend_asset.head.code	31	100.0

问题

1,不是小表驱动大表吗,为什么这里大表驱动小表效率更高

2,针对第一个sql,line表驱动时,排序好像比不排序,效率更高,line表不排序type=all,排序反而是index为什么

3,数据库中总共有15万数据,需要导出,每次查询1000,分页查询,大表驱动小表和小表驱动大表,影响最终的分页结果吗,比如导出数量有影响吗

4,采用第一个sql,又想不遗漏head数据(head无line关联数据),需要保证正确导出分页,怎么使用union优化

回答

1

确实,在大多数JOIN优化场景中,我们通常推荐"小表驱动大表"的原则,但您这个案例却出现了相反的情况。让我详细解释为什么这里"大表驱动小表"反而更快:

为什么这个特例中大表驱动小表更快

  1. LEFT JOIN的特殊性

    • 您使用的是LEFT JOIN,不是INNER JOIN

    • LEFT JOIN的逻辑是:必须返回左表的所有行,无论右表是否有匹配

    • 第一个查询(大表驱动):

      sql

      复制

      下载

      FROM asset_fa_disposal_line(line) LEFT JOIN asset_fa_disposal(head)

      优化器知道必须返回line表所有141,466行,所以选择全表扫描line,然后对每行快速查找head

  2. 索引效率差异

    • head.code有uniq_code索引(唯一索引),查找速度极快(O(1)复杂度)

    • line.parent_code有普通索引,查找速度稍慢

    • 大表驱动时:141,466次唯一索引查找

    • 小表驱动时:4,832次普通索引查找,每次返回约31行(总共约150,000行)

  3. 数据分布特点

    • 每个head.code平均对应约31个line记录(141466/4832≈29.3)

    • 这种"一对多"关系使得从小表出发会导致更多中间结果

  4. 执行成本对比

    • 大表驱动:141,466次高效唯一索引查找

    • 小表驱动:4,832次范围查找,每次返回约31行,需要处理更多数据页

何时"大表驱动小表"更优

  1. LEFT JOIN且右表有极高效索引

  2. 右表的查找条件比左表的选择性更好

  3. 数据关系是一对多且"多"的一方数据量极大

  4. 查询需要返回左表大多数行时(如无WHERE条件)

验证方法

您可以尝试以下实验验证:

sql

复制

下载

-- 强制小表驱动大表
SELECT /*+ JOIN_ORDER(head, line) */ ... FROM head LEFT JOIN line ...-- 强制大表驱动小表 
SELECT /*+ JOIN_ORDER(line, head) */ ... FROM line LEFT JOIN head ...

总结

"小表驱动大表"是通用原则,但在LEFT JOIN、特殊索引结构和特定数据分布下,可能会出现大表驱动更优的情况。优化器根据成本估算选择了更适合当前表结构和数据分布的执行计划。

2

您观察到了一个非常有意思的现象,这涉及到MySQL优化器的工作机制。让我详细解释为什么在第一种查询中(line表驱动),加上ORDER BY line.id DESC后执行效率反而更高:

核心原因:MySQL的"排序驱动优化"

当查询包含ORDER BY且使用LIMIT时,MySQL优化器会尝试"优先排序后连接"的策略:

  1. 无排序时(性能较低)

    • type=ALL表示全表扫描line表(141,466行)

    • 对每一行再通过索引查找head表

    • 最后才应用LIMIT 1000

  2. 有排序时(性能更高)

    • type=index且显示"Backward index scan"表示优化器选择:

      • 直接按id索引的逆序扫描(从最大id开始)

      • 只需扫描1000行满足LIMIT的数据

      • 然后对这1000行做关联查询

    • 避免了全表扫描

关键技术点

  1. Backward index scan(反向索引扫描)

    • InnoDB索引默认是升序排列的

    • 当使用ORDER BY id DESC时,MySQL 8.0+可以智能地从索引尾部开始反向扫描

    • 只需读取满足LIMIT的行数(1000行)即可停止

  2. LIMIT的优化作用

    sql

    复制

    下载

    ORDER BY line.id DESC LIMIT 1000
    • 告诉优化器"我只需要1000条排好序的记录"

    • 优化器会优先使用id索引直接定位到符合条件的记录

  3. 索引覆盖优势

    • 虽然您的查询选择了很多列,但排序只依赖line.id

    • id是主键,索引结构本身就包含全部排序信息

执行流程对比

无排序流程:

复制

下载

1. 全表扫描line表(141,466行)
2. 对每行查找head表
3. 组合所有结果
4. 应用LIMIT 1000

有排序流程:

复制

下载

1. 从line表的id索引尾部开始反向扫描
2. 扫描1000行后停止(不读全表)
3. 对这1000行查找head表
4. 返回结果

为什么第二种方式(head驱动)没有这种优化

当head表驱动时:

  • 排序字段(line.id)不在驱动表

  • MySQL必须先完成全部连接操作

  • 生成包含所有字段的临时结果集(约150,000行)

  • 然后排序这个巨大临时表

  • 最后应用LIMIT

最佳实践建议

  1. 排序字段应尽量来自驱动表

  2. 确保排序字段有索引(如您案例中的line.id)

  3. 结合LIMIT使用ORDER BY可以触发这种优化

  4. 对于分页查询,这种模式性能最好

这种优化特别适合:

  • 大型事实表关联小型维度表

  • 需要最新/最旧记录的查询

  • 分页展示场景

您的案例完美展示了当表结构设计合理(line.id有主键索引)时,MySQL优化器能够发挥的强大优化能力。

3

分页查询驱动方式对导出结果的影响分析

在您的场景中(15万数据,每次查询1000条分页导出),驱动方式的选择确实会影响最终导出结果,但影响的性质取决于您的具体需求。

两种驱动方式对结果的影响

1. 大表驱动小表(line LEFT JOIN head)
  • 结果特点

    • 保证line表的所有记录都会出现在结果中

    • 如果某些line记录没有对应的head记录,head相关字段为NULL

    • 结果数量 = line表的记录数(15万)

2. 小表驱动大表(head LEFT JOIN line)
  • 结果特点

    • 保证head表的所有记录都会出现在结果中

    • 如果某些head记录没有对应的line记录,line相关字段为NULL

    • 结果数量 ≥ head表的记录数(因为有1对多关系)

关键差异点

  1. 结果集基数不同

    • 大表驱动:结果行数=line表行数(15万)

    • 小表驱动:结果行数≈head表行数×平均关联数(4832×31≈15万)

  2. NULL记录出现位置不同

    • 大表驱动:可能出现head字段为NULL的记录

    • 小表驱动:可能出现line字段为NULL的记录

  3. 分页边界问题

    • 两种方式的分页切分点可能不同,因为记录排序不同

    • 特别是当使用ORDER BY时,排序字段的位置会影响分页边界

导出数量是否受影响?

  • 如果只是简单导出所有关联数据:两种方式导出的总记录数应该相同(15万),因为您描述的是1对多关系且数据完整

  • 如果有NULL记录过滤:导出数量可能会有差异

  • 如果使用ORDER BY:分页边界不同可能导致某些记录在不同页中出现

实际建议

  1. 业务需求决定驱动方式

    • 如果需要确保不遗漏任何line记录 → 使用line驱动

    • 如果需要确保不遗漏任何head记录 → 使用head驱动

  2. 导出一致性保障

    sql

    复制

    下载

    -- 推荐使用游标方式而非分页导出,确保数据一致性
    DECLARE cur CURSOR FOR 
    SELECT ... FROM line LEFT JOIN head ... ORDER BY line.id;-- 或者使用基于ID的范围查询
    SELECT ... FROM line LEFT JOIN head 
    WHERE line.id > last_id ORDER BY line.id LIMIT 1000;
  3. 性能考虑

    • 如您之前发现的,line驱动+ORDER BY line.id性能更好

    • 对于大批量导出,建议使用这种高效方式

  4. 导出验证

    • 可以在导出完成后检查两种方式的记录数是否匹配预期

    • 特别检查边界条件记录是否都被包含

总结:驱动方式主要影响的是结果集的组成和顺序,在1对多关系且数据完整的情况下,总导出量应该相同,但具体哪些记录出现在哪些分页中可能会有差异。

4

SELECT * FROM (-- 有关联的记录SELECT /* 字段列表 */,1 as record_type,line.id as sort_keyFROM asset_fa_disposal headJOIN asset_fa_disposal_line line ON head.code = line.parent_codeUNION ALL-- 无关联的记录SELECT /* 字段列表 */,2 as record_type,head.code as sort_keyFROM asset_fa_disposal headWHERE NOT EXISTS (SELECT 1 FROM asset_fa_disposal_line WHERE parent_code = head.code)
) combined
ORDER BY record_type, sort_key DESC
LIMIT 1000 OFFSET 0;

http://www.dtcms.com/wzjs/46812.html

相关文章:

  • 北京国都建设集团网站百度网站名称
  • 美女和帅哥做私人动作的漫画的网站关键词优化如何做
  • 品牌服装网站建设现状一般开车用什么导航最好
  • 有没有在线做动图的网站百度竞价托管外包代运营
  • 重庆网站制作企业百度广告电话号码
  • 做网站开封世界杯大数据
  • 做资源网站怎么不封北京网络营销推广培训哪家好
  • 学校网站源码php今日时政新闻
  • 国外在线网站建设平台西安seo网站排名
  • 网站整站个人建站
  • 手机做网站公司有哪些怎么在百度上设置自己的门店
  • 如何建设电影会员网站今日热点新闻头条国内
  • 人妖怎么做的手术视频网站网络运营师资格证
  • 如何建设公司网站知乎搜索引擎营销案例分析题
  • 电子商务网站开发项目设计报告阿里云搜索引擎网址
  • 西宁网站建设平台公司广州线下培训机构停课
  • 个人做慈善网站百度账户登录
  • 重庆市渝兴建设投资有限公司网站中视频自媒体平台注册
  • 外贸网址大全百度问答优化
  • 网站是用sql2012做的_在发布时可以改变为2008吗推广之家官网
  • 网站建设资质备案百度人工服务24小时热线电话
  • 专做医药中间体的网站百度关键词优化点击 教程
  • 泉做网站的公司廊坊百度快照优化哪家服务好
  • 亦庄建设局网站手机端怎么刷排名
  • 北京燕郊网站建设seo软件
  • 加强政府网站建设管理的重要性360推广登录
  • 浅谈顺丰的电子商务网站建设设计个人网站
  • 苏州网页优化软件优化疫情防控
  • 网站建设基本网络推广文案
  • 江苏省建设工程网站推广手段有哪些