sql >> データベース >  >> RDS >> Sqlserver

varchar 列をテキストで更新する最速の方法

    これは「最速」に関する質問なので、タイミングを以下に示します

    テスト セットアップ、100 万行を超えるテーブル

    create table MetaDataServe (id int identity primary key, vc varchar(max));
    
    insert MetaDataServe values
    ('MindWorks.Accounts'),
    ('MindWorks.Transactions'),
    ('MindWorks.Commissions');
    
    insert MetaDataServe
    select vc
    from MetaDataServe, master..spt_values a, master..spt_values b
    where b.number between 1 and 30
    -- (1090110 row(s) affected)
    

    もの vs 置換 vs サブストリング

    パフォーマンスの概要 - STUFF> SUBSTRING> REPLACE

    update MetaDataServe set vc = STUFF(vc, 9, 0, '.Client')
    

    (2 つの時間は変動性を示すために複数回実行したものです。非常に低いため、時間は 3% 以内の精度であると見なすことができます)

    update MetaDataServe set vc = REPLACE(vc, '.', '.Client.')
    
    update MetaDataServe set vc = 'MindWorks.Client.' + SUBSTRING(vc, 11, 100)
    

    固定数 vs PATINDEX vs CHARINDEX

    (固定位置バージョンは既に上で与えられています)
    パフォーマンスの概要 - FIXED> (PATINDEX =CHARINDEX)

    update MetaDataServe set vc = STUFF(vc, PATINDEX('%.%',vc), 0, '.Client')
    
    update MetaDataServe set vc = STUFF(vc, CHARINDEX('.',vc), 0, '.Client')
    

    注:

    • 上記のすべての更新ステートメントは、必要に応じて (1 つか 2 つの微調整で) 機能します
    • 各テストの前に、キャッシュの問題を防ぐためにテーブル全体が削除され、再作成されます

    注意!

    STUFF の方が高速ですが、トリッキーな状況に陥ることがあります。データに

    が含まれている場合
    "MindWorksNoDot"
    

    そして、

    を使用して更新します
    update MetaDataServe set vc = STUFF(vc, CHARINDEX('.',vc), 0, '.Client')
    

    あなたはNULLになってしまいます! CHARINDEX がドットを見つけられない場合、STUFF の 2 番目のパラメータがゼロ (0) であるため、文字列全体が NULL になります。 .

    最後に

    安全性と信頼性のために、STUFF アプローチよりも 33% 遅いだけなので、単純に REPLACE ステートメントを使用します。つまり、

    update MetaDataServe set vc = REPLACE(vc, '.', '.Client.')
    


    1. LOAD_FILEを使用してファイルをMySQLBLOBにロードする方法は?

    2. OracleAnalytics-SQLクエリのパーティションと順序

    3. PHPMySqlを使用した高度なニュースアーカイブの年/月

    4. 外部サーバーに参加/プッシュダウンする前にサブクエリの評価を強制する方法