限制 SQL 查询仅扫描少于 500 条记录的表
Limit SQL query to only scan tables with less than 500 records
我创建了以下脚本,它遍历我数据库所有字段中的所有值。
然而,这是一项非常耗时的任务,因此我希望将其限制为仅遍历包含 500 条或更少记录的 tables,并跳过充满无关紧要的大 tables无论如何数据。
我在弄清楚如何将我的 COUNT 包含在 table 中时遇到问题,因为我正在使用 varchar(256) 作为 table 名称。
USE [Name of Database]
DECLARE @SearchStr nvarchar(100) = 'Text to search fields for'
DECLARE @Results TABLE (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
SET @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')
WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
BEGIN
SET @ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
AND TABLE_NAME = PARSENAME(@TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'int', 'decimal')
AND QUOTENAME(COLUMN_NAME) > @ColumnName
)
IF @ColumnName IS NOT NULL
BEGIN
INSERT INTO @Results
EXEC
(
'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630)
FROM ' + @TableName + ' (NOLOCK) ' +
' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM @Results
如有任何帮助或建议,我们将不胜感激?
您需要做的就是计算 table 的计数并应用
这样的条件
if(select count(*) from table_name)<500
begin
execute your query
end
您可以使用系统 table sys.dm_db_partition_stats 查找具有 500 多条记录的 table。
/* Returns tables with 500+ rows,
* using the system tables.
*/
SELECT
s.name,
o.name,
st.row_count
FROM
sys.objects AS o
INNER JOIN sys.schemas AS s ON s.schema_id = o.schema_id
INNER JOIN sys.dm_db_partition_stats st ON st.object_id = o.object_id
WHERE
o.type = 'U' -- User defined is a table.
AND st.index_id IN (0, 1) -- 0 = Heap, 1 = Clustered index.
AND st.row_count > 500
ORDER BY
st.row_count DESC
;
返回的行数是一个近似值。除非您需要 100% 的准确性,否则它应该符合您的目的。我针对十亿条记录加数据库测试了查询,发现所有行计数都与基础 tables 完全匹配。有关详细信息,请参阅 docs。
您可以使用 sys.dm_db_partition_stats table 的近似方法。只需按照此代码添加 JOIN 即可:
...
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
--add this JOIN
JOIN
(
SELECT
object_name(object_id) as Table_Name
FROM sys.dm_db_partition_stats
WHERE (index_id < 2)
GROUP BY object_name(object_id)
HAVING SUM(row_count)<=500
) as Stat
ON INFORMATION_SCHEMA.TABLES.TABLE_NAME = Stat.Table_Name
-- add this JOIN
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
...
更多详情:
Fastest way to count exact number of rows in a very large table?
我创建了以下脚本,它遍历我数据库所有字段中的所有值。
然而,这是一项非常耗时的任务,因此我希望将其限制为仅遍历包含 500 条或更少记录的 tables,并跳过充满无关紧要的大 tables无论如何数据。
我在弄清楚如何将我的 COUNT 包含在 table 中时遇到问题,因为我正在使用 varchar(256) 作为 table 名称。
USE [Name of Database]
DECLARE @SearchStr nvarchar(100) = 'Text to search fields for'
DECLARE @Results TABLE (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
SET @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')
WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
BEGIN
SET @ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
AND TABLE_NAME = PARSENAME(@TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'int', 'decimal')
AND QUOTENAME(COLUMN_NAME) > @ColumnName
)
IF @ColumnName IS NOT NULL
BEGIN
INSERT INTO @Results
EXEC
(
'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630)
FROM ' + @TableName + ' (NOLOCK) ' +
' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM @Results
如有任何帮助或建议,我们将不胜感激?
您需要做的就是计算 table 的计数并应用
这样的条件if(select count(*) from table_name)<500
begin
execute your query
end
您可以使用系统 table sys.dm_db_partition_stats 查找具有 500 多条记录的 table。
/* Returns tables with 500+ rows,
* using the system tables.
*/
SELECT
s.name,
o.name,
st.row_count
FROM
sys.objects AS o
INNER JOIN sys.schemas AS s ON s.schema_id = o.schema_id
INNER JOIN sys.dm_db_partition_stats st ON st.object_id = o.object_id
WHERE
o.type = 'U' -- User defined is a table.
AND st.index_id IN (0, 1) -- 0 = Heap, 1 = Clustered index.
AND st.row_count > 500
ORDER BY
st.row_count DESC
;
返回的行数是一个近似值。除非您需要 100% 的准确性,否则它应该符合您的目的。我针对十亿条记录加数据库测试了查询,发现所有行计数都与基础 tables 完全匹配。有关详细信息,请参阅 docs。
您可以使用 sys.dm_db_partition_stats table 的近似方法。只需按照此代码添加 JOIN 即可:
...
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
--add this JOIN
JOIN
(
SELECT
object_name(object_id) as Table_Name
FROM sys.dm_db_partition_stats
WHERE (index_id < 2)
GROUP BY object_name(object_id)
HAVING SUM(row_count)<=500
) as Stat
ON INFORMATION_SCHEMA.TABLES.TABLE_NAME = Stat.Table_Name
-- add this JOIN
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
...
更多详情: Fastest way to count exact number of rows in a very large table?