2012-07-26 78 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