2012-07-26 75 views
1

我需要在一个非常大的数据库中查找一个ID。 ID为:在大型数据库中搜索特定ID?

0167a901-e343-4745-963c-404809b74dd9 

该数据库包含数百个表和数百万行大表中的行。

我可以缩小日期到最后的2或3个月之内,但仅此而已。我正在寻找任何关于如何缩小搜索范围的线索。

有一两件事我很好奇的是使用LIKE搜索是否有帮助。

即它有助于像做

select top 10 * 
from BIG_TABLE 
where DESIRED_ID like '016%' 

任何提示/建议高度赞赏。数据库正在远程访问,所以这是挑战的一部分

+1

您定义了哪些索引? – mellamokb 2012-07-26 18:27:03

+2

我假设你不知道什么表的ID在...你知道它可能在什么专栏? – Randy 2012-07-26 18:28:29

+0

@mellamokb - 好问题 - 所以有一些查询列(LK_xyz,LK_abc) - 那些索引正确 – Coffee 2012-07-26 18:28:52

回答

2

我有几年前为了类似目的而创建的这个脚本,尽管有文本字段。它找到符合条件的列,然后在这些列中搜索该值。由于你有一个非确定性的范围,你可能无法做得比这个更好。

您可能需要稍微调整它以包含uniqueidentifier列 - 如果这实际上是数据类型 - 或者使用等号而不是类似的搜索。

如果这是你要定期重用的东西,你可以给它一个普通表或列的列表来找到这些东西,所以它不需要很长时间才能找到东西。

/*This script will find any text value in the database*/ 
/*Output will be directed to the Messages window. Don't forget to look there!!!*/ 

SET NOCOUNT ON 
DECLARE @valuetosearchfor varchar(128), @objectOwner varchar(64) 
SET @valuetosearchfor = '%putYourGuidHere%' --should be formatted as a like search 
SET @objectOwner = 'dbo' 

DECLARE @potentialcolumns TABLE (id int IDENTITY, sql varchar(4000)) 

INSERT INTO @potentialcolumns (sql) 
SELECT 
    ('if exists (select 1 from [' + 
    [tabs].[table_schema] + '].[' + 
    [tabs].[table_name] + 
    '] (NOLOCK) where [' + 
    [cols].[column_name] + 
    '] like ''' + @valuetosearchfor + ''') print ''SELECT * FROM [' + 
    [tabs].[table_schema] + '].[' + 
    [tabs].[table_name] + 
    '] (NOLOCK) WHERE [' + 
    [cols].[column_name] + 
    '] LIKE ''''' + @valuetosearchfor + '''''' + 
    '''') as 'sql' 
FROM information_schema.columns cols 
    INNER JOIN information_schema.tables tabs 
     ON cols.TABLE_CATALOG = tabs.TABLE_CATALOG 
      AND cols.TABLE_SCHEMA = tabs.TABLE_SCHEMA 
      AND cols.TABLE_NAME = tabs.TABLE_NAME 
WHERE cols.data_type IN ('char', 'varchar', 'nvchar', 'nvarchar','text','ntext') 
    AND tabs.table_schema = @objectOwner 
    AND tabs.TABLE_TYPE = 'BASE TABLE' 
    AND (cols.CHARACTER_MAXIMUM_LENGTH >= (LEN(@valueToSearchFor) - 2) OR cols.CHARACTER_MAXIMUM_LENGTH = -1) 
ORDER BY tabs.table_catalog, tabs.table_name, cols.ordinal_position 

DECLARE @count int 
SET @count = (SELECT MAX(id) FROM @potentialcolumns) 
PRINT 'Found ' + CAST(@count as varchar) + ' potential columns.' 
PRINT 'Beginning scan...' 
PRINT '' 
PRINT 'These columns contain the values being searched for...' 
PRINT '' 
DECLARE @iterator int, @sql varchar(4000) 
SET @iterator = 1 
WHILE @iterator <= (SELECT Max(id) FROM @potentialcolumns) 
BEGIN 
    SET @sql = (SELECT [sql] FROM @potentialcolumns where [id] = @iterator) 
    IF (@sql IS NOT NULL) and (RTRIM(LTRIM(@sql)) <> '') 
    BEGIN 
     --SELECT @sql --use when checking sql output 
     EXEC (@sql) 
    END 
    SET @iterator = @iterator + 1 
END 

PRINT '' 
PRINT 'Scan completed' 

如果看起来靠不住的,在脚本执行如下语句

if exists (select 1 from [schema].[table_name] (NOLOCK) 
        where [column_name] LIKE '%yourValue%') 
begin 
    print select * from [schema].[table_name] (NOLOCK) 
        where [column_name] LIKE '%yourValue%' 
end 

...,只是更换[schema][table_name][column_name]%yourValue%在一个循环。

其过滤上...

  • 表中的一个特定的模式(滤波器可以移除
  • 只表,而不是视图(可以调整
  • 仅列,其将保存搜索值
  • (n)char/(n)varchar/(n)text数据类型(添加或更改,将cogni zant数据类型转换

最后,输出不会转到结果网格。检查消息窗口(您看到“受影响的N行”)

+0

非常感谢你 - 我需要仔细研究这个!谢谢 !! – Coffee 2012-07-27 13:00:20

+0

绝对没有工作。 – 2017-02-23 10:52:09

+0

@DavidAndreiNed - 这已经工作了多年。你有没有发现你的案件中缺少什么? – StingyJack 2017-02-23 12:49:59

1

设置DESIRED_ID部分的Index

如果在此表中没有Index,数据库引擎执行Table scanreads every row检查DESIRED_ID就像是“016”,并确保正确indexing总是导致相当大的性能提升

CREATE INDEX NameIndex ON TableName(ColumnName ASC) 
INCLUDE (ColumnName2) 

实施Index将搜索从016开始到017或02或类似1的记录。无论它先找到什么,然后停止搜索。

虽然准备Dynamic query找到样本GUID值在所有表中的数据。您可以使用以下查询来查找特定表下列名称中的数据。

select * from sys.columns where name = 'ColumnName' OBJECT_ID = 
(Select OBJECT_ID From sys.tables Where name = 'Object Name') 
1

首先是什么,为什么你需要特定的价值形态whoel database.It看起来像一个兼职,以发现价值,并根据您将采取一些action.But也可以是时间的要求和资源消耗。

不管怎么说,它看起来像一个GUID列。 除非所有的guid列都有索引,否则无法加快速度。

反正这里是一个小的查询,这将产生在具有任何GUID列(如果这是一些VARCHAR列则是非常困难的,因为你必须写上IOF每个表中每列的查询中的所有表的SELECT语句你可以写,但我不认为这将是有效的)。

然而,最重要的是,输出基于following..If有指数,并在GUID列那么这些表列在第一领先键进行排序。 然后根据数据页列出表,以便查询使用最少的资源。因此,如果您的GUID值是在最初的几个表这将是非常fast.If这将是在上表中它会根据表的大小时间,因此可能需要大量的时间。

此外,声明此查询的光标,然后由一个执行语句之一,只要你找出来的游标循环的GUID的值是唯一的价值。将更加高效。

select * from (
select 'select ' + ac.name +' from ' + OBJECT_SCHEMA_NAME(ac.object_id) + '.' + OBJECT_NAME(ac.object_id) + ' where ' + ac.name + '=''29490167a901-e343-4745-963c-404809b74dd9''' as querytext 
--,* 
,isnull(cnt,0) as numberofrows, 
ROW_NUMBER() over(order by case when ic.key_ordinal = 0 then 0 else 1 end asc, isnull(si.dpages,si_1.dpages) asc) as rn,isnull(si.dpages,si_1.dpages) datapages 
from sys.all_columns ac 
inner join sys.all_objects ao on ac.object_id = ao.object_id 
left join sys.index_columns ic on ac.object_id=ic.object_id 
and ac.column_id =ic.column_id 
left join sys.sysindexes si on ac.object_id = si.id and ic.index_id=si.indid 
outer apply (select SUM(rows) from sys.partitions p where ac.object_id = p.object_id and index_id in (0,1)) a(cnt) 
left join sys.sysindexes si_1 on si_1.id =ac.object_id and si_1.indid in (0,1) 
where system_type_id =36 
and ao.type ='U' 
) dta order by rn asc 
go