簡體   English   中英

如何在具有不同數據類型的多列上搜索大量數據?

[英]How to search huge data on multiple column with different datatypes?

我有一個這樣的DataElement表:

 DataElement table 
 ValueAsBoolean : bit nullable
 ValueAsDatetime : datetime2 nullable
 ValueAsDecimal : decimal(10,3) nullable
 ValueAsInt : int nullable
 ValueAsString : nvarchar(100) nullable

數據將如下所示:

ValueAsBoolean 值作為日期時間 十進制值 ValueAsInt 值作為字符串
1 無效的 無效的 無效的 無效的
無效的 2022-09-03 12:30:01.210 無效的 無效的 無效的
無效的 無效的 23.000 無效的 無效的
無效的 無效的 無效的 5 無效的
無效的 無效的 無效的 無效的 蒙塔利公司

我想在與輸入搜索關鍵字匹配的所有列中搜索數據。

  • 可以通過 TIME ZONE 搜索ValueAsDatetime並在 UI 上顯示格式
  • 對於ValueAsBoolean可以通過文本“TRUE”、“FALSE”或“TRUE”或“FALSE”的一部分進行搜索
  • 對於ValueAsStringValueAsIntValueAsDecimal可以按輸入文本的一部分進行搜索

例如,給定 2022-09-03 12:30:01.210 是 2022 年 9 月 9 日星期二

用戶輸入“T”。

輸出將是行

  • 1 因為“T”與 ValueAsBoolean 1 ( T RUE) 匹配
  • 2 因為“ T ”與“Tue, 9 Sep 2022”匹配
  • 5 因為“T”與“MON T ARY INC.”匹配

因此,我通過以下方式創建基於 EF 核心的查詢:

  1. 將所有列轉換為字符串值
  2. 格式化值
  3. 檢查值是否包含搜索關鍵字

查詢將如下所示:

SELECT *
FROM [DataElement]
WHERE 
    (([ValueAsBoolean] IS NOT NULL AND (('T' = N'')
    OR (CHARINDEX('T', LOWER( CASE WHEN ValueAsBoolean = 1 then 'true' else 'false' END)) > 0))) 
    OR ([ValueAsDateTime] IS NOT NULL AND (('T' = N'') 
    OR (CHARINDEX('T', LOWER( FORMAT(CONVERT(DATETIME, SWITCHOFFSET( [ValueAsDateTime], DATEPART(TZOFFSET, ValueAsDateTime AT TIME ZONE 'UTC' ))), 'ddd, d MMM yyyy H:mm:ss' ))) > 0)))) 
    OR ([ValueAsDecimal] IS NOT NULL AND (('T' = N'')
    OR (CHARINDEX('T', LOWER(CONVERT(VARCHAR(100), [ValueAsDecimal]))) > 0)))) 
    OR ([ValueAsInt] IS NOT NULL AND (('T' = N'')
    OR (CHARINDEX('T', LOWER(CONVERT(VARCHAR(11), [ValueAsInt]))) > 0)))) 
    OR ([ValueAsString] IS NOT NULL AND (('T' = N'')
    OR (CHARINDEX('T', LOWER([ValueAsString])) > 0)))

問題是當數據很大時(超過 500000 條記錄)需要很長時間來處理(超過 30 秒)並且超過查詢超時限制。

我的問題是如何在這樣的多個列上搜索大量數據?

我認為的一個選擇是將新列創建為 NVARCHAR(100),將多個 COLUMN 上的數據轉換並保存到該列中,將索引設置為該列並僅搜索該列,但我不能為日期時間應用搜索格式。

或者有其他解決方案嗎?

試試下面的代碼。 使用此代碼,您可以在所有數據庫表的所有字段中進行搜索。 稍作改動,您可以將表名添加為過濾器並僅在所需表中搜索:

DECLARE @SearchStr nvarchar(100)
SET @SearchStr = 'Put Search String Here'
CREATE TABLE #Results (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
DROP TABLE #Results

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM