mysql - MySQL 是将整行加载到内存中,还是只加载 WHERE、ORDER BY 和 GROUP BY 中使用的列?

标签 mysql database performance memory

我有一个表格,它的行数不是很大(在 100ks 范围内),但包含大量原始数据,而且大小非常大。尽管行数相对较少,但大约为 1.5GB。

所以了解MySQL是将整行加载到内存中,还是只加载WHERE、ORDER BY和GROUP BY中使用的列和执行查询时的索引,以及最后的其余列是非常重要的?

查询示例:

SELECT HugeDataTable.*, Table2.Name
FROM Table1
LEFT JOIN Table2 ON Table1.`ID` = Table2.`Table1ID` 
LEFT JOIN HugeDataTable FORCE INDEX(RowOrder) ON Table2.`ID` = HugeDataTable.`Table2ID` 
WHERE HugeDataTable.Category = 5 AND Table1.ExampleColumn = integerExampleValue
AND HugeDataTable.RowOrder >10000 AND HugeDataTable.ID <> "h4324h534"
ORDER BY HugeDataTable.`RowOrder` DESC LIMIT 18 ;

使用 Explain SELECT 我设法发现 MySQL 每个查询扫描大约 70k 行。查询速度相当快,但我不确定这是否是行缓存的原因,因为我无法模拟服务器上的重负载。

所以,我的问题是,在查询将结果限制为 18 行后,是否会加载包含大量原始数据的列,从而最终只加载所需的少量原始数据?

或者它们会在限制之前加载,所以 70k 行,即大约 1GB 的数据值(value)在限制之前加载?如果是后一种情况,可以采取什么措施来防止这种情况发生,因为服务器只有 1GB 的 RAM。

编辑:我添加了 EXPLAIN。

id  select_type  table          type    possible_keys                       key               key_len  ref                           rows   Extra                     
1   SIMPLE       HugeDataTable  range   Table2ID,Category,RowOrder          RowOrder          9                                      49591  Using where               
1   SIMPLE       Table2         eq_ref  PRIMARY                             PRIMARY           10       const,HugeDataTable.Table2ID  1      Using where; Using index  
1   SIMPLE       Table1         ref     PRIMARY                             PRIMARY           2        Table2.Table1ID               1                       

最佳答案

下次你问这样的问题时,你能不能包括 EXPLAIN 计划。

通常使用 LEFT JOIN,mysql 将在连接之前解析表之前的表之后(尽管并非总是如此)因此它将首先从表 1 读取行,然后是表 2,然后是 HugeDataTable。

但您的问题相当困惑 - 您不需要在查询输出中包含 WHERE、ORDER BY 和 GROUP BY 中的列。 SELECT * 绝不是一个好主意。唯一需要注意的是,如果您有多个查询所需列的组合,那么您将无法充分利用查询缓存。

但是这个查询在许多其他方面非常效率低下。为什么要按双左连接表中的值进行排序和限制?即使您的数据完整性完全崩溃,也有比这更好的解决方案。正如 aconrad 所说,您实现了一个非常昂贵的 INNER JOIN - 而不是此处的 LEFT JOIN。

强制索引通常是获得糟糕执行计划的好方法。

关于mysql - MySQL 是将整行加载到内存中,还是只加载 WHERE、ORDER BY 和 GROUP BY 中使用的列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21118639/

相关文章:

php - 如何在进入数据库后触发请求?

android - 如何显示mysql数据库中的图片?

mysql - sql查询合并列

database - 从使用原始导出创建的 Oracle dmp 中提取信息

css - 在 prestashop 中缩小 CSS 和 JS

android - 我应该使用什么来获得更好的性能,九补丁或可绘制的 xml 资源?

mysql - 查询两个具有不同列但一个列之间没有关系的表

php - 与跟踪器/持久器的高效数据库交互

performance - 额外的日期范围过滤器是否会提高性能?

mysql - 在 MySQL 中插入 100 万条记录