在排序 table 中找到所有日期后,停止使用 "between dates" 条件进一步检查查询
Stop query from checking further with "between dates" condition after all dates are found in sorted table
我有一个非常大的 table,其中有一列包含日期。由于 table 太大,我想请求数据,例如每一天,我都试图用以下语句来做:
SELECT *
FROM [my_db].[dbo].[my_data] where date between '2019-03-25' and '2019-03-26'
到目前为止一切顺利,当我运行这个查询时,返回了相关数据(大约10,000行)。但是,查询并没有停止,它一直在执行很长时间(看不到多长时间,我总是在大约 30 分钟后停止)。
我假设它正在检查更合适的日期。但是,table 已排序,因此 我 知道不会再有任何日期。
在这里处理这个问题的最佳方法是什么?没有找到进一步的结果后,有没有办法设置某种超时?或者我应该只使用正常超时并希望交易及时完成?谢谢!
听起来您的查询正在执行 table scan
来检索您的数据。
我们对您的硬件性能一无所知,但对于大型 table,可能高度分散,这在慢速驱动器上或 IO 成为瓶颈时可能是一项耗时的操作。
您可以通过多种方式快速获得大概的行数。阅读您提到的评论,您是在笔记本电脑上执行此操作,因此您很可能是唯一的用户,在这种情况下,大概的计数可能是正确的。
最简单的就是运行
exec sp_spaceused 'tablename'
您可以查询 table
上的索引列表
select * from sys.indexes where object_id=Object_Id('tablename')
您还可以在 SSMS 中使用 Object Explorer Details 查看所有 table 的列表及其统计信息,包括行。连接到您的服务器并从对象资源管理器的列表中展开数据库。打开 Details 面板 (F7) 并单击 Tables,将填充列表并检索行数。
您还可以在对象资源管理器中展开 Tables
,展开您的特定 table,然后展开 Indexes
以查看当前定义的内容。
因为您(可能)在您的 Date
列上没有索引,即使 您 知道您已经收到所有符合条件的结果,SQL 服务器不会,因为它必须扫描 table。没有索引,就无法保证一定范围内的行都按顺序存在。
这意味着它从一端跳入并开始逐页阅读直到读到最后,检查每一行以查看它是否符合您的过滤条件。如果您期望的数据恰好驻留在它读取的第一页上,那么很好 - 但 SQL 服务器无法知道它已找到每个可能的合格行 - 许多因素(例如页面碎片)可能意味着某些行可能进一步存在沿着构成 table 数据的页面列表。
date
列上的索引会有很大帮助,因为这样 SQL 服务器可以 直接搜索 到第一个合格日期的开始并读取values in order 直到它到达最后一个符合条件的行,因为数据是 sorted 它知道它已经到达末尾。
索引也有助于查询 select count(*)
。每个索引(过滤索引除外)包括每一行,但不是每一列 - 因此要获得行数 SQL 服务器将扫描 narrowest 索引,这意味着它将具有尽可能少的 IO。
此外,如果您实际上 不需要 ,则执行 select *
每一列都会对性能产生影响。
如果您的查询是高度选择性的,并且您在 date
上有一个索引,SQL 服务器将在索引中查找所需的行,然后执行 书签查找 检索剩余的列。
然而,这是一个昂贵的操作,因此存在一个阈值,在该阈值中权衡是不值得的,SQL服务器将选择扫描 table 而不是避免查找操作。
我有一个非常大的 table,其中有一列包含日期。由于 table 太大,我想请求数据,例如每一天,我都试图用以下语句来做:
SELECT *
FROM [my_db].[dbo].[my_data] where date between '2019-03-25' and '2019-03-26'
到目前为止一切顺利,当我运行这个查询时,返回了相关数据(大约10,000行)。但是,查询并没有停止,它一直在执行很长时间(看不到多长时间,我总是在大约 30 分钟后停止)。 我假设它正在检查更合适的日期。但是,table 已排序,因此 我 知道不会再有任何日期。
在这里处理这个问题的最佳方法是什么?没有找到进一步的结果后,有没有办法设置某种超时?或者我应该只使用正常超时并希望交易及时完成?谢谢!
听起来您的查询正在执行 table scan
来检索您的数据。
我们对您的硬件性能一无所知,但对于大型 table,可能高度分散,这在慢速驱动器上或 IO 成为瓶颈时可能是一项耗时的操作。
您可以通过多种方式快速获得大概的行数。阅读您提到的评论,您是在笔记本电脑上执行此操作,因此您很可能是唯一的用户,在这种情况下,大概的计数可能是正确的。
最简单的就是运行
exec sp_spaceused 'tablename'
您可以查询 table
上的索引列表select * from sys.indexes where object_id=Object_Id('tablename')
您还可以在 SSMS 中使用 Object Explorer Details 查看所有 table 的列表及其统计信息,包括行。连接到您的服务器并从对象资源管理器的列表中展开数据库。打开 Details 面板 (F7) 并单击 Tables,将填充列表并检索行数。
您还可以在对象资源管理器中展开 Tables
,展开您的特定 table,然后展开 Indexes
以查看当前定义的内容。
因为您(可能)在您的 Date
列上没有索引,即使 您 知道您已经收到所有符合条件的结果,SQL 服务器不会,因为它必须扫描 table。没有索引,就无法保证一定范围内的行都按顺序存在。
这意味着它从一端跳入并开始逐页阅读直到读到最后,检查每一行以查看它是否符合您的过滤条件。如果您期望的数据恰好驻留在它读取的第一页上,那么很好 - 但 SQL 服务器无法知道它已找到每个可能的合格行 - 许多因素(例如页面碎片)可能意味着某些行可能进一步存在沿着构成 table 数据的页面列表。
date
列上的索引会有很大帮助,因为这样 SQL 服务器可以 直接搜索 到第一个合格日期的开始并读取values in order 直到它到达最后一个符合条件的行,因为数据是 sorted 它知道它已经到达末尾。
索引也有助于查询 select count(*)
。每个索引(过滤索引除外)包括每一行,但不是每一列 - 因此要获得行数 SQL 服务器将扫描 narrowest 索引,这意味着它将具有尽可能少的 IO。
此外,如果您实际上 不需要 ,则执行 select *
每一列都会对性能产生影响。
如果您的查询是高度选择性的,并且您在 date
上有一个索引,SQL 服务器将在索引中查找所需的行,然后执行 书签查找 检索剩余的列。
然而,这是一个昂贵的操作,因此存在一个阈值,在该阈值中权衡是不值得的,SQL服务器将选择扫描 table 而不是避免查找操作。