查询在具有 300 万个条目的大型数据库 table 上花费太多时间,如何优化性能
Query taking too much time on a large database table with 3 million entries,how to optimize the performance
Spring 引导查询
@Query(value="SELECT *
FROM products p
join product_generic_name pg on pg.id = p.product_generic_name_id
where (p.product_name like %?1%
and p.parent_product_id IS NULL
and p.is_active=true and
(p.is_laboratory is null or p.is_laboratory = false)
)
or (pg.product_generic_name like %?1%
and pg.is_active = true) ",nativeQuery = true)
Page<Products> findByProductNameLikeAndGenericNameLike(String searchText, Pageable pageable);
产品 table 有超过 300 万个条目,查询需要大约 4 分钟到 complete.How 以优化查询性能。我尝试为 product_name 列编制索引,但没有太大的性能改进。
我会说这是一个非常开放的问题。
我会尽力给你破解的
除非您还没有,否则您可以做一些事情。
技巧 1:优化查询
在许多情况下,数据库性能问题是由低效的 SQL 查询引起的。优化 SQL 查询是提高数据库性能的最佳方法之一。当您尝试手动执行此操作时,您会在选择如何最好地提高查询效率方面遇到一些难题。其中包括了解是编写连接查询还是子查询,是使用 EXISTS 还是 IN,等等。当您知道最佳前进路径时,您可以编写提高效率的查询,从而提高整个数据库的性能。这意味着更少的瓶颈和更少的不满意的最终用户。
优化查询的最佳方法是使用数据库性能分析解决方案,该解决方案可以指导您进行优化工作,方法是将您引导至效率最低的查询并提供有关如何最好地改进它们的专家建议。
技巧 2:改进索引
除了查询之外,数据库的另一个基本要素是索引。如果做得好,索引可以提高数据库性能并帮助优化查询执行的持续时间。索引创建了一种数据结构,有助于使您的所有数据井井有条,并使查找信息变得更加容易。因为更容易找到数据,索引提高了数据检索的效率并加快了整个过程,为您和系统节省了时间和精力。
技巧 3:整理数据碎片
数据碎片整理是提高数据库性能的最佳方法之一。随着时间的推移,不断有如此多的数据被写入数据库和从数据库中删除,您的数据可能会变得支离破碎。这种碎片会减慢数据检索过程,因为它会干扰查询快速定位所需信息的能力。当您对数据进行碎片整理时,您允许将相关数据组合在一起并消除索引页面问题。这意味着您的 I/O 相关操作将 运行 更快。
技巧四:增加内存
当您没有足够的内存供数据库正常工作时,数据库的效率会受到严重影响。即使您看起来总共有很多内存,您也可能无法满足数据库的需求。确定您是否需要更多内存的一个好方法是检查您的系统有多少页面错误。当故障数量很高时,这意味着您的主机要么 运行ning 低可用内存,要么完全用完可用内存。增加内存分配将有助于提高效率和整体性能。
技巧 5:强化 CPU
更好的 CPU 直接转化为更高效的数据库。这就是为什么如果您遇到数据库性能问题,您应该考虑升级到更高的 class CPU 单元。您的 CPU 越强大,处理多个请求和应用程序时的压力就越小。在评估您的 CPU 时,您应该跟踪 CPU 性能的所有元素,包括 CPU 就绪时间,它告诉您系统尝试使用 CPU, 但不能,因为资源被其他方式占用了
向 product_name 添加索引不会有帮助,因为您正在对其进行类似搜索,而不是完全匹配。对于您的查询,您应该将索引添加到:
- is_active
- is_laboratory
- parent_product_id
然而,在搜索的开始和结束时使用两个通配符进行“自由文本”搜索对于关系数据库来说并不是一个很好的用例。这是这个问题的最佳设计吗?如果您有 300 万种产品,您是否可以使用用户必须 select 来减少要搜索的行数的“product_group”?或者,这是一个非常适合 ElasticSearch 或 Solr 等全文搜索引擎的用例。
有两个瓶颈:
like %?1%
-- 前导通配符意味着它必须读取并检查每一行。
OR
-- 这很少可优化。
如果 like %?1%
只查看“单词”,那么使用 FULLTEXT
索引和 MATCH
会 运行 快得多。
OR
可以变成UNION
。它可能应该是 UNION DISTINCT
,假设 ?1
可以在 name
和 generic_name
中。
更多内存、更多常规索引等等——这些不太可能会有帮助。 EXPLAIN
和其他分析工具告诉您 现在发生了什么 ,而不是如何改进查询 and/or 索引。碎片整理(在 InnoDB 中)主要是浪费时间。 CPU 速度范围很窄;这在 20 多年里没有改变。额外的核心是无用的,因为 MySQL 将只使用一个核心来进行此查询。仅仅 3M 行意味着您可能拥有足够的 RAM。
Spring 引导查询
@Query(value="SELECT *
FROM products p
join product_generic_name pg on pg.id = p.product_generic_name_id
where (p.product_name like %?1%
and p.parent_product_id IS NULL
and p.is_active=true and
(p.is_laboratory is null or p.is_laboratory = false)
)
or (pg.product_generic_name like %?1%
and pg.is_active = true) ",nativeQuery = true)
Page<Products> findByProductNameLikeAndGenericNameLike(String searchText, Pageable pageable);
产品 table 有超过 300 万个条目,查询需要大约 4 分钟到 complete.How 以优化查询性能。我尝试为 product_name 列编制索引,但没有太大的性能改进。
我会说这是一个非常开放的问题。
我会尽力给你破解的
除非您还没有,否则您可以做一些事情。
技巧 1:优化查询 在许多情况下,数据库性能问题是由低效的 SQL 查询引起的。优化 SQL 查询是提高数据库性能的最佳方法之一。当您尝试手动执行此操作时,您会在选择如何最好地提高查询效率方面遇到一些难题。其中包括了解是编写连接查询还是子查询,是使用 EXISTS 还是 IN,等等。当您知道最佳前进路径时,您可以编写提高效率的查询,从而提高整个数据库的性能。这意味着更少的瓶颈和更少的不满意的最终用户。
优化查询的最佳方法是使用数据库性能分析解决方案,该解决方案可以指导您进行优化工作,方法是将您引导至效率最低的查询并提供有关如何最好地改进它们的专家建议。
技巧 2:改进索引 除了查询之外,数据库的另一个基本要素是索引。如果做得好,索引可以提高数据库性能并帮助优化查询执行的持续时间。索引创建了一种数据结构,有助于使您的所有数据井井有条,并使查找信息变得更加容易。因为更容易找到数据,索引提高了数据检索的效率并加快了整个过程,为您和系统节省了时间和精力。
技巧 3:整理数据碎片 数据碎片整理是提高数据库性能的最佳方法之一。随着时间的推移,不断有如此多的数据被写入数据库和从数据库中删除,您的数据可能会变得支离破碎。这种碎片会减慢数据检索过程,因为它会干扰查询快速定位所需信息的能力。当您对数据进行碎片整理时,您允许将相关数据组合在一起并消除索引页面问题。这意味着您的 I/O 相关操作将 运行 更快。
技巧四:增加内存 当您没有足够的内存供数据库正常工作时,数据库的效率会受到严重影响。即使您看起来总共有很多内存,您也可能无法满足数据库的需求。确定您是否需要更多内存的一个好方法是检查您的系统有多少页面错误。当故障数量很高时,这意味着您的主机要么 运行ning 低可用内存,要么完全用完可用内存。增加内存分配将有助于提高效率和整体性能。
技巧 5:强化 CPU 更好的 CPU 直接转化为更高效的数据库。这就是为什么如果您遇到数据库性能问题,您应该考虑升级到更高的 class CPU 单元。您的 CPU 越强大,处理多个请求和应用程序时的压力就越小。在评估您的 CPU 时,您应该跟踪 CPU 性能的所有元素,包括 CPU 就绪时间,它告诉您系统尝试使用 CPU, 但不能,因为资源被其他方式占用了
向 product_name 添加索引不会有帮助,因为您正在对其进行类似搜索,而不是完全匹配。对于您的查询,您应该将索引添加到:
- is_active
- is_laboratory
- parent_product_id
然而,在搜索的开始和结束时使用两个通配符进行“自由文本”搜索对于关系数据库来说并不是一个很好的用例。这是这个问题的最佳设计吗?如果您有 300 万种产品,您是否可以使用用户必须 select 来减少要搜索的行数的“product_group”?或者,这是一个非常适合 ElasticSearch 或 Solr 等全文搜索引擎的用例。
有两个瓶颈:
like %?1%
-- 前导通配符意味着它必须读取并检查每一行。OR
-- 这很少可优化。
如果 like %?1%
只查看“单词”,那么使用 FULLTEXT
索引和 MATCH
会 运行 快得多。
OR
可以变成UNION
。它可能应该是 UNION DISTINCT
,假设 ?1
可以在 name
和 generic_name
中。
更多内存、更多常规索引等等——这些不太可能会有帮助。 EXPLAIN
和其他分析工具告诉您 现在发生了什么 ,而不是如何改进查询 and/or 索引。碎片整理(在 InnoDB 中)主要是浪费时间。 CPU 速度范围很窄;这在 20 多年里没有改变。额外的核心是无用的,因为 MySQL 将只使用一个核心来进行此查询。仅仅 3M 行意味着您可能拥有足够的 RAM。