MySQL派生表查询大数据量无结果问题分析与解决

通过子查询优化MySQL复杂数据统计查询的性能技巧 例如,统计每个部门的员工数量时,可以使用派生表代替WHERE子句中的子查询,这样MySQL优化器可以更有效地制定执行计划,减少重复计算。在统计查询中,如果子查询需要访问的列都包含在索引中,MySQL可以直接使用索引完成查询而无需访问数据表,这被称为覆盖索引扫描,能极大减少磁盘I/O操作。性能瓶颈主要出现在相关子查询对外部查询的每一行都执行一次内部查询,造成所谓的N+1查询问题。对于大数据集,这种差异会显著影响查询速度。此外,确保EXISTS子查询中的条件列有适当的索引,可以进一步加速查询执行过程。 阅读详情

MySQL派生表查询大数据量无结果问题分析与解决

一、问题发现

在客户现场的一次问题报告中发现某个带有派生表进行查询的时候,数据量少的时候有结果,但是数据量大的时候返回无记录。看下面例子:

1、准备表

CREATE TABLE `cmdb_item` (
  `cm_item_id` varchar(350) NOT NULL,
  `cm_model_id` varchar(350) NOT NULL,
  PRIMARY KEY (`cm_item_id`,`cm_model_id`)
);
CREATE TABLE `sys_auth_role_cmdb` (
  `id` varchar(60) NOT NULL,
  `auth_type_id` varchar(60) DEFAULT NULL,
  `cmdb_item_id` varchar(60) DEFAULT NULL,
  `cmdb_model_id` varchar(60) DEFAULT NULL,
  `role_id` varchar(60) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

2、一条数据场合

如下所示插入一条数据并且进行派生表查询,可以发现结果有一条数据,符合预期。

greatsql> SELECT b.* FROM( SELECT cmdb_item_id FROM sys_auth_role_cmdb where1=0 union SELECT cm_item_id FROM cmdb_item) a LEFT JOIN cmdb_item b ON a.cmdb_item_id = b.cm_item_id WHERE b.cm_model_id='PmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmq' and
cm_item_id='8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J';

+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| cm_item_id                                                                                                                                                                                                                                                       | cm_model_id                                                                                                                                                                                                                                                      |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J | PmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmq |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (3.50 sec)

3、插入大量数据的场合

-- 首先设置tmp_table_size参数为合适的值
SET LOCAL tmp_table_size=2000000;

set sql_mode="oracle";
delimiter $$
CREATE or replace PROCEDURE p1() as
BEGIN
  for i in 1 .. 5000 loop
    insert into cmdb_item values('8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J'|| i,'PmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmq' || i);
  end loop;
END$$
delimiter ;
--插入5000条数据
call p1();

--执行跟上面一样的查询,可以发现结果为空,此处为问题
greatsql> SELECT b.* FROM( SELECT cmdb_item_id FROM sys_auth_role_cmdb where1=0 union SELECT cm_item_id FROM cmdb_item) a LEFT JOIN cmdb_item b ON a.cmdb_item_id = b.cm_item_id WHERE b.cm_model_id='PmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmq' and cm_item_id='8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J';
Empty set (0.00 sec)

4、tmp_table_size值最小的场合

-- 设置tmp_table_size参数为最小值
SET LOCAL tmp_table_size=1024;

-- 执行跟上面一样的查询,可以发现结果跟只有一条数据时候一样,出现一条数据
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| cm_item_id                                                                                                                                                                                                                                                       | cm_model_id                                                                                                                                                                                                                                                      |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J | PmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmq |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (3.50 sec)

5、对比执行计划

查看上面几个场合的执行计划,结果如下:

数据量为1的场合执行计划:

greatsql> explain analyze SELECT b.* FROM( SELECT cmdb_item_id FROM sys_auth_role_cmdb where1=0 union SELECT cm_item_id FROM cmdb_item) a LEFT JOIN cmdb_item b ON a.cmdb_item_id = b.cm_item_id WHERE b.cm_model_id='PmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmq' and cm_item_id='8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J';
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| EXPLAIN                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| -> Constant row from a  (cost=1207.97..1207.97 rows=1) (actual time=1107.026..1107.027 rows=1 loops=1)
    -> Union materialize with deduplication  (cost=1207.62..1207.62 rows=4553) (actual time=1106.831..1106.831 rows=5001 loops=1)
        -> Zero rows (Impossible WHERE)  (cost=0.00..0.00 rows=0) (actual time=0.000..0.000 rows=0 loops=1)
        -> Covering index scan on cmdb_item using PRIMARY  (cost=752.32 rows=4553) (actual time=0.723..69.643 rows=5001 loops=1)
 |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (1.11 sec)

数据量为5001的场合执行计划,可以看到下面的执行计划跟上面是一样的,不同点在于最后一步Constant row from a 这段的rows=0,说明执行计划没问题,但是执行阶段有问题。

greatdb> explain analyze SELECT b.* FROM ( SELECT cmdb_item_id FROM sys_auth_role_cmdb WHERE 1=0 UNION SELECT cm_item_id FROM cmdb_item) a LEFT JOIN cmdb_item b ON a.cmdb_item_id = b.cm_item_id WHERE b.cm_model_id='PmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmqPmqECfANKxmbpgt3XBWaxzF6dx32dLmq' AND cm_item_id='8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J8b0zIlHsiarv8Ls6NejWji6Cu4h3iN2J';
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| EXPLAIN                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| -> Constant row from a  (cost=1053.17..1053.17 rows=1) (actual time=1118.948..1118.948 rows=0 loops=1)这个地方rows=0说明问题在这里
    -> Union materialize with deduplication  (cost=1052.82..1052.82 rows=4553) (actual time=1118.946..1118.946 rows=5001 loops=1)
        -> Zero rows (Impossible WHERE)  (cost=0.00..0.00 rows=0) (actual time=0.001..0.001 rows=0 loops=1)
        -> Covering index scan on cmdb_item using PRIMARY  (cost=597.52 rows=4553) (actual time=2.315..70.077 rows=5001 loops=1)
 |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (1.13 sec)
二、问题调查过程

查询带有派生表的时候内部会创建临时表用于保存临时数据,因此先看一下上面几个场合的临时表情况:

tmp_table_size值数据量查询开始时候临时表情况查询过程中临时表情况说明
20000001条数据内存表内存表没问题
20000005001条数据内存表转为落盘表问题
10245001条数据落盘表落盘表没问题

先看一下读取数据的代码:

int ConstIterator::Read() {
  if (!m_first_record_since_init) {
    return -1;
  }
  m_first_record_since_init = false;
  // 这里打印err结果为-1,跳进read_const看一下为何没有数据返回
  int err = read_const(table(), m_ref);
  if (err == 0 && m_examined_rows != nullptr) {
    ++*m_examined_rows;
  }
  table()->const_table = true;
  return err;
}

int read_const(TABLE *table, Index_lookup *ref) {
  int error;
  DBUG_TRACE;
  // 数据为一条的时候会进入这个if线正常读数据,但是数据为5001条的时候却没进入这个if线,可见问题在table的这个状态。
  // 这里要求table->m_status = STATUS_NOT_STARTED才会进入
  if (!table->is_started())  // If first read
    这里面读取表数据
  } else if (table->has_row() && table->is_nullable()) {}
  return table->has_row() ? 0 : -1;
}

考虑上面的现象,数据量少和数据量多的场合结果不一样,这里面的区别在于union在查询阶段会创建临时物化表用于储存union结果,数据量少的时候在内存就可以创建物化表出结果了,但是如果数据量大的话,因为内存不够放,因此需要重新创建落盘表用于储存查询结果。

又考虑到上面<<tmp_table_size值最小的场合>>这节,把内存表值改小结果又正常,因此可以推测是内存临时表改为落盘表后table的is_started()状态值改变了导致结果为空。这里可以从创建落盘表入手。找到创建落盘表的函数create_ondisk_from_heap()并且打个断点,看看堆栈:

#0  create_ondisk_from_heap (
    thd=0x55555accb1a0 <native_rw_unlock(native_rw_lock_t*)+24>, wtable=0x7fffc83eddc0, 
    error=0, insert_last_record=false, ignore_last_dup=false, is_duplicate=0x0)
    at sql/sql_tmp_table.cc:2777
#1  0x0000555559b98fb2 in MaterializeIterator<DummyIteratorProfiler>::MaterializeQueryBlock (this=0x7fff2023f390, query_block=..., stored_rows=0x7fffc83eef10)
    at sql/iterators/composite_iterators.cc:1433
#2  0x0000555559b9649e in MaterializeIterator<DummyIteratorProfiler>::Init (
    this=0x7fff2023f390)
    at sql/iterators/composite_iterators.cc:975
#3  0x00005555597dae49 in Query_expression::ExecuteIteratorQuery (this=0x7fff2026d310, 
    thd=0x7fff20001050)
    at sql/sql_union.cc:1814
#4  0x00005555597db287 in Query_expression::execute (this=0x7fff2026d310, 
    thd=0x7fff20001050)
    at sql/sql_union.cc:1877
#5  0x0000555559700334 in Sql_cmd_dml::execute_inner (this=0x7fff20224010, 
    thd=0x7fff20001050)
    at sql/sql_select.cc:872
#6  0x00005555596ff502 in Sql_cmd_dml::execute (this=0x7fff20224010, thd=0x7fff20001050)
    at sql/sql_select.cc:612
#7  0x00005555596621f0 in mysql_execute_command (thd=0x7fff20001050, first_level=true)
    at sql/sql_parse.cc:5227
#8  0x0000555559664838 in dispatch_sql_command (thd=0x7fff20001050, 
    parser_state=0x7fffc83f0760, update_userstat=false)
    at sql/sql_parse.cc:5905
#9  0x0000555559658b03 in dispatch_command (thd=0x7fff20001050, com_data=0x7fffc83f1210, 
    command=COM_QUERY)

查看MaterializeIterator::MaterializeQueryBlock函数代码,追踪一下table->is_started()状态值:

bool MaterializeIterator<Profiler>::MaterializeQueryBlock(
    error = t->file->ha_write_row(t->record[0]);

    if (error == 0) {
      ++*stored_rows;
      continue;
    }
    // create_ondisk_from_heap will generate error if needed.
    if (!t->file->is_ignorable_error(error)) {
      bool is_duplicate;
      // 这里table->m_status = STATUS_NOT_STARTED | STATUS_NOT_FOUND,正常初始值,符合预期
      if (create_ondisk_from_heap(thd(), t, error,
                                  /*insert_last_record=*/true,
                                  /*ignore_last_dup=*/true, &is_duplicate))
        return true; /* purecov: inspected */
      // 这里执行完create_ondisk_from_heap以后table->m_status = STATUS_NOT_FOUND,可见在create_ondisk_from_heap函数内部改变了这个m_status
}
查看create_ondisk_from_heap代码,看一下哪个地方改变了table->m_status值。
bool create_ondisk_from_heap(THD *thd, TABLE *wtable, int error,
                             bool insert_last_record, bool ignore_last_dup,
                             bool *is_duplicate) {
        // 执行下面这句的时候因为调用了table->set_row_status_from_handler(result)改变了m_status值,先从3变为0最后变为2
        // 状态迁移情况:STATUS_NOT_STARTED | STATUS_NOT_FOUND ==> 0 ==> STATUS_NOT_FOUND
        while (!table->file->ha_rnd_next(new_table.record[1])) {
          write_err = new_table.file->ha_write_row(new_table.record[1]);
          DBUG_EXECUTE_IF("raise_error", write_err = HA_ERR_FOUND_DUPP_KEY;);
          if (write_err) goto err_after_open;
        }
}

发现果然是create_ondisk_from_heap函数改变了table->is_started()状态值,所以导致了结果为空。

三、问题解决

结合上面分析,我们可以把代码作如下修复,就可以解决这个问题了。

bool MaterializeIterator<Profiler>::MaterializeQueryBlock(
    error = t->file->ha_write_row(t->record[0]);

    if (error == 0) {
      ++*stored_rows;
      continue;
    }
    // create_ondisk_from_heap will generate error if needed.
    if (!t->file->is_ignorable_error(error)) {
      bool is_duplicate;
      if (create_ondisk_from_heap(thd(), t, error,
                                  /*insert_last_record=*/true,
                                  /*ignore_last_dup=*/true, &is_duplicate))
        return true; /* purecov: inspected */
      // 这里把table->is_started()状态复原即可,问题解决。
      t->set_not_started();
}

接着执行上面的查询,发现可以查出结果了。

四、问题总结

通过以上分析我们可以发现,带有派生表的查询会在内部创建临时表用于储存中间数据,根据tmp_table_size值设置会影响临时表存放地方,如果tmp_table_size设置小了那么一开始就会创建落盘表,如果设置大了那么创建的就是内存表,随着数据的增加后面可能会转为落盘表,因此才有了本文章提及的bug。分析类似问题的时候,需要结合查询计划的执行和临时表创建情况分析,才能更好解决问题。

MySQL多表查询核心指南 , > 比较运算符。 阅读详情

相关推荐

MySQL 8.0 多表关联查询实战:3种JOIN语法解决电商与社交推荐场景

本文深入解析MySQL 8.0中三种JOIN语法在电商交易分析和社交推荐场景的应用实践。通过INNER JOIN、LEFT JOIN及子查询的性能对比测试,揭示优化策略,帮助开发者高效处理多表关联查询,提升数据库操作效率。

weixin_30301449的博客 453

MySQL查询结果自动添加序号的五种实战方案

在数据库查询中,为结果集添加序号是常见的需求,尤其在数据分析和报表生成场景中。MySQL虽然没有内置的ROWNUM伪列,但通过用户变量和窗口函数等技术手段,可以实现灵活的行号生成。用户变量方案利用会话变量的自增特性,适用于MySQL 5.7及以下版本;而MySQL 8.0+则支持更高效的窗口函数,如ROW_NUMBER(),性能提升显著。这些技术不仅适用于简单的序号添加,还能处理分区排序、分页查询等复杂场景。合理选择方案可以优化查询性能,特别是在大数据量或分布式环境下。本文通过五种实战方案,帮助开发者解决M

weixin_34026276的博客 442

MySQL多表查询实战:联合、连接与子查询的性能优化与避坑指南

在关系型数据库系统中,多表查询是处理复杂业务逻辑的核心技术,它基于关系代数和集合运算原理,通过组合不同表中的数据来满足业务需求。这项技术的价值在于能够高效地整合分散的数据,支撑起用户画像、订单分析、报表统计等关键应用场景。在实际工程实践中,联合查询(UNION/UNION ALL)用于纵向合并数据集,连接查询(JOIN)实现表的横向关联,而子查询则提供了嵌套逻辑的灵活性。本文将深入探讨这些技术的底层机制,特别是针对连接查询的索引优化策略和子查询的性能陷阱,帮助开发者在处理大数据量关联时,避免全表扫描和笛卡尔

diandingyin9417的博客 396

MySQL查询结果添加序号的五种实用方案与性能对比

在数据库查询中,为结果集添加序号是常见的需求,尤其在数据分析和报表生成场景。SQL通过变量自增、窗口函数等技术实现行号生成,其核心原理是利用会话变量或分析函数进行计数。从技术价值看,正确的序号生成方案能显著提升查询效率,特别是在处理大数据量时。MySQL 8.0+的窗口函数方案符合SQL标准且性能优越,而用户变量方案则具有更好的版本兼容性。实际应用中需要根据MySQL版本、数据量大小和排序需求选择合适方案,例如用户变量适合MySQL 5.6+环境,窗口函数则在分组排序场景表现更佳。合理使用这些技术可以优化分

weixin_34221775的博客 421

MySQL多表查询本质:关系代数、执行顺序与NULL陷阱

多表查询是SQL数据操作的核心能力,其底层逻辑源于关系代数中的笛卡尔积、选择与投影运算。理解JOIN的物理执行流程(ON过滤→WHERE二次筛选→GROUP BY聚合)是写出正确SQL的前提,尤其需厘清LEFT JOIN中ON与WHERE对NULL值的不同处理机制。该技术直接决定查询结果准确性与性能表现,在教育、金融、电商等OLTP系统中高频应用。本文聚焦MySQL DQL多表查询的语义本质、典型误用模式及EXPLAIN调优方法,覆盖驱动表选择、索引下推、IS NULL判断等关键实践要点。

weixin_34239169的博客 432

MySQL联表查询:多表关联与嵌套查询指南

MySQL复杂查询高级指南 本文系统讲解了MySQL复杂查询的核心技术,包括: 多表连接(INNER JOIN/LEFT JOIN等)及其应用场景 各类子查询(标量、列、行、表)的使用方法 联合查询(UNION/UNION ALL)的区别与适用场景 临时表与派生表的使用技巧 综合实战案例演示复杂查询应用 掌握这些高级查询技术,能够有效处理真实业务中的多表数据关联、复杂数据筛选和结果集合并等需求,提升数据库操作效率和分析能力。文章还提供了性能优化建议和下一步学习方向。

DN金猿的博客 171

MySQL查询结果动态生成序号的5种实现方案

在数据库查询中,动态生成行号是常见的业务需求,特别是在数据展示和报表导出场景。SQL中的行号功能可以帮助开发者快速标识数据位置,实现分页排序等核心功能。从技术实现看,MySQL提供了多种生成序号的方法,包括用户变量自增、窗口函数ROW_NUMBER()等。其中用户变量方案兼容MySQL各版本,通过变量初始化和自增实现简单计数;而MySQL 8.0引入的窗口函数则遵循SQL标准,支持PARTITION BY分组编号。这些技术在用户管理系统、数据分析平台等场景都有广泛应用,特别是结合索引优化后,能有效提升大数据

weixin_33462927的博客 244

工程师必看:如何用定时截尾试验快速验证产品MTBF(附真实案例解析)

本文为硬件工程师详细解析了如何运用定时截尾试验快速验证产品MTBF(平均无故障工作时间)。通过七步实战法,结合工业物联网网关的真实案例,阐述了从参数设定、试验执行到结果判读的完整流程,并提供了MATLAB脚本实现自动化计算与可视化,帮助工程师在有限时间内科学评估产品可靠性。

weixin_29243063的博客 494

MySQL查询结果自动生成序号的5种方法

在数据库操作中,结果集排序与序号生成是数据处理的基础需求。通过窗口函数、会话变量等技术手段,可以在SQL查询层面实现高效的行号标记,避免全量数据传输到应用层的性能损耗。ROW_NUMBER()等窗口函数利用数据库引擎的优化能力,在排序计算时能有效利用索引提升性能。实际业务场景如金融对账、成绩排名等都需要保持序号的连续性和可追溯性,特别是在分页查询时要求全局序号一致。本文详解的会话变量方案兼容MySQL全版本,而临时表技巧则适合处理千万级大数据量,这些方法配合适当的索引设计,能显著提升查询效率。

weixin_34021089的博客 440

Xshell 连接 kali 虚拟机教程

启动ssh服务,启动后重新查看ssh服务状态,如下图active(running)正常。至此便可以直接使用Xshell登录kali系统了。至此虚拟机已经可以上网。-查看ssh服务状态。

qq_40726937的博客 2219

【Docker】如何让docker容器正常使用nvidia显卡

描述了如何在docker容器中使用英伟达显卡的过程和问题解决方法。

NameLoadingFailed的博客 8372

MySQL多表查询实战:JOIN、UNION与子查询的深度解析与性能优化

在数据库开发中,多表查询是处理复杂业务逻辑的核心技术,它通过连接、合并和嵌套查询,将分散在不同表中的数据重组为业务视角的完整信息。其原理在于利用表间关系(如主外键)进行数据关联,通过JOIN实现横向扩展,UNION实现纵向合并,子查询实现嵌套逻辑。这项技术的价值在于能够高效解决现实世界中的数据关联需求,例如电商系统中的用户-订单-商品关联分析、跨表统计报表生成等。在实际应用中,掌握连接查询(尤其是内连接与外连接的区别)、联合查询的去重与性能权衡,以及子查询的多种形式(如标量、列、EXISTS子查询)至关重要

weixin_30587927的博客 423

QT使用高精度定时器

精度相对第二种方法高许多。

ljjjjjjjjjjj的博客 4097

临时表和子查询的区别

SQL查询优化对比:临时表(A)与子查询(B)两种写法在逻辑上等效,但执行层面存在差异。临时表适用于复杂查询和大数据场景,具有可复用性、分步调试和可控性优势;子查询则更简洁,适合简单的一次性查询。MySQL 8.0+优化器缩小了性能差距。建议根据查询复杂度、数据量和复用需求选择合适方案,复杂场景优先考虑临时表,简单查询可使用子查询。

m0_65545927的博客 508

centos7部署mysql8.0.35,主从复制,主主集群

centos7 linux部署mysql,主从复制,主主模式

zaixiaqin的博客 1990

<PLC><西门子><工控>西门子博图V18中使用SCL语言编写一个CRC16-modbus校验程序

西门子官方对于SCL语言的介绍如下:SCL 编程语言SCL 编程语言SCL(Structured Control Language,结构化控制语言)是一种基于 PASCAL 的高级编程语言。这种语言基于标准DIN EN 61131-3(国际标准为 IEC 1131-3)。根据该标准,可对用于可编程逻辑控制器的编程语言进行标准化。SCL 编程语言实现了该标准中定义的 ST 语言 (结构化文本) 的PLCopen 初级水平。语言元素。

用沸腾的热血,支付我们的人生吧! 1436

MySQL多表查询优化与实战技巧

关系型数据库的多表查询是数据处理的核心技术,通过JOIN操作实现表间关联。其原理是基于关联字段建立表关系,执行时先筛选单表数据再进行笛卡尔积计算。优化多表查询能显著提升系统性能,尤其在电商订单、社交网络等高频查询场景中。实战中需掌握INNER JOIN、LEFT JOIN等连接方式,合理使用索引和EXISTS子查询。MySQL 8.0引入的Hash Join技术大幅提升无索引连接效率,而递归CTE则简化了层级数据处理。这些技术在百万级数据量的ERP、电商系统中已验证其价值。

weixin_34345753的博客 281

【AI智能体】Codex 生成高质量电商套图实战操作详解

Codex 生成高质量电商套图实战操作详解

congge 4525

MySQL子查询全解析:从基础语法到性能优化实战

在数据库查询语言SQL中,子查询是一种嵌套在其他查询内部的查询结构,它通过‘查询中的查询’机制实现复杂的数据筛选与关联。其核心原理是将内部查询的结果作为外部查询的条件或数据源,从而构建多层逻辑的数据处理流程。这一技术对于实现高级数据分析和复杂业务逻辑具有重要价值,能够解决诸如‘查找高于部门平均工资的员工’、‘筛选有订单的客户’等常见业务场景。在实际应用中,子查询可分为标量、列、表和行等多种类型,并衍生出IN、EXISTS等关键操作符。其中,相关子查询与EXISTS操作符的合理使用,能显著提升查询效率,而IN

weixin_33672109的博客 567

飞牛fnNAS虚拟机开启OVS导致失联的解决

摘要:用户在使用飞牛NAS时发现开启OVS网络功能后导致NAS失联。通过多种尝试(包括开关OVS、更换系统版本、手工配置、更换网卡、处理器检查等)后发现,OVS启用状态下DHCP无法获取IP地址,手动设置IP可暂时恢复网络。但重启后问题依旧,初步判断为OVS功能存在bug。目前临时解决方案是在需要时手动开关OVS,或考虑其他虚拟化方案。用户计划后续探索替代方案,并等待官方修复该问题。

dgnankai的专栏 4334

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

MySQL 视图(VIEW)性能对比:5表JOIN查询与视图封装效率实测

本文深入评测了MySQL视图(VIEW)在5表JOIN查询中的性能表现,通过实际测试数据对比直接JOIN查询与视图封装的效率差异。测试结果显示视图会引入约3-8%的性能开销,特别是在首次执行和复杂查询场景下差异更明显。文章还提供了视图优化策略和实际场景决策指南,帮助开发者在数据库优化中做出合理选择。

weixin_30425949的博客 403

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

MySQL高级查询技巧全解析

JOIN 用于将多个表中的数据基于关联字段组合起来,常见的 JOIN 类型包括 INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL JOIN。对于复杂的 JOIN 和子查询,应考虑添加适当的索引以提高查询性能。MySQL 的 JOIN、子查询与嵌套查询是数据库操作中常用的高级查询技术,用于处理复杂的数据关系和多表关联场景。子查询是嵌套在另一个查询中的查询,可以出现在 SELECT、FROM、WHERE 等子句中。嵌套查询是子查询的延伸,指多层嵌套的查询结构。

mWgRpKj1eD的博客 233

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

掌握MySQL多表查询:从JOIN原理到实战优化全解析

在关系型数据库系统中,数据通常按照范式设计分散存储于多张表中,通过主键和外键建立关联。多表查询的核心原理在于连接(JOIN)操作,它允许我们将这些分散的数据表根据关联条件重新组合,从而提取出完整的业务信息。从技术价值看,多表查询是数据库查询能力的核心体现,直接决定了数据分析的深度和业务系统开发的效率。在应用场景上,无论是电商平台的订单用户关联分析、企业ERP系统的跨模块数据统计,还是商业智能中的多维报表生成,都离不开高效的多表查询。本文聚焦于**MySQL JOIN**的实战应用与**SQL性能优化**,深

weixin_30263277的博客 279

MySQL limit查询 百万级别数据分页查询优化的两种方式

注 : index_id 为主键索引 即 PRIMARY 一 生成测试数据 参考 文章 MySQL快速生成大量测试数据1000万 二 测试 1.创建索引 建表时已经设置了 id 是自增主键 在innoDB存储引擎中 自增主键默认作为聚蔟索引 2.分页查询 2.1 通常方式 #测试 LIMIT 测试 select * from t limit 1900000,10 可以看到执行时间为0.36秒 对执行计划进行分析 可以看到 type 是 ALL 也就是最慢的全表扫描,操作了二百一十万行记录 2.

纸上得来终觉浅,绝知此事要躬行 1301

SQL改写进阶:标量子查询的“隐形代价”与消除实战

标量子查询是SQL中最容易被忽视的性能陷阱之一。一条看似简洁的SQL,可能因为标量子查询而让查询时间从毫秒级变成分钟级。本文从标量子查询的执行机制出发,用“嵌套循环”的比喻讲清楚它为什么慢,并通过真实案例演示如何用派生表、窗口函数等方式消除标量子查询,帮助读者写出既简洁又高效的SQL。

DBAxiaoye的博客 383
上一篇: GreatSQL从库报错13146:字符集不一致问题处理
下一篇: 终止分区表变更操作时误删数据字典缓存导致MySQL崩溃分析
GreatSQL社区
博客等级 码龄5年 1210粉丝 390原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值