最经济高效的方式来翻阅排序不佳的表格?

bee*_*eks 7 sql-server paging

我有一个包含三列的表:HashUID1、HashUID2、Address_Name(这是一个文本电子邮件地址,前两个哈希列是将事件参与者表链接到电子邮件地址的疯狂创建。它丑陋,几乎无法解决由我控制。专注于 address_name 索引)

它有 7800 万行。没有正确排序。无论如何,该索引被拆分到许多快速 LUN 上并执行非常快速的索引查找。

我需要创建一系列查询以一次仅提取 20,000 个“每页行”,但要避免冲突或欺骗。由于没有标识列或易于排序的列,是否有一种简单的方法可以全选并翻页?

我说的是否正确,如果我将 select * from hugetablewithemails 放入临时表,然后通过 row_number 通过它选择该表在事务期间保留在内存中,对我来说,这是过多的内存资源? 这似乎是首选的分页方法。我宁愿按统计百分比分页。:(

有一个索引按顺序维护 address_name 电子邮件地址,并且维护得很好。在过去的一周里,我一直想通过花费一些时间来研究构建一个基于统计的窗口函数吐出范围的过程(我不擅长,但这个查询真的让我感兴趣)来帮助其他开发人员提供索引的一系列字符 1 到(变量)LEFT LIKE 字符,满足 20,000 行——但我什至没有时间开始查询......

几个问题:

  1. 有什么建议?不是在寻找实际的代码,只是一些基于经验的提示或建议,也许是警告。我想避免在初始扫描后进行额外的索引扫描。

  2. 这是正确的方法吗?

  3. 我正在考虑打破所有电子邮件地址的索引总和,收集行数(*),/20,000,并将其用作窗口函数,根据总行数的百分比对最小/最大子字符串(1,5)值进行分组建立分组范围。想法?

这是针对无法修改源数据库的 ETL 过程。

我希望通过一次完整的索引扫描,我可以做到:

  • 查询以根据索引使用情况(按字母顺序排序)获取直方图,并使用 min/max 将其分解(窗口化)以创建这样的一些范围,以便轻松查找所需的索引:

  • A-> AAAX,(例如 20k 行)AAA-Z,B->(另外 20k),B->BAAR -> BAAR-> CDEFG -> CDEFH > FAAH,等等。

我们为这个 ETL 过程在这些数据库中运行读提交。我们只尝试将它批量处理成 20k 行,因为 DBA 说我们通过抓取完整的表格使用了太多的网络资源。如果数据发生了变化(这是一个问题),我们会即时更新我们的 DW 和临时表。

喜欢用临时表,但如果我这样做,我会溢出到tempdb中,并获得关于其从DBA的圈套通过电子邮件和数据库太大。

Pau*_*ite 9

本质上,您是在询问是否可以对整个数据执行单次有序扫描,同时不制作数据副本,并在每次调用时从完整集中返回“x”个不相交的行集。这正是适当配置的 API 游标的行为。

例如,使用 AdventureWorks 表Person.EmailAddress返回 1,000 行的集合:

DECLARE 
    @cur integer,
    -- FAST_FORWARD | AUTO_FETCH | AUTO_CLOSE
    @scrollopt integer = 16 | 8192 | 16384,
    -- READ_ONLY, CHECK_ACCEPTED_OPTS, READ_ONLY_ACCEPTABLE
    @ccopt integer = 1 | 32768 | 65536, 
    @rowcount integer = 1000,
    @rc integer;

-- Open the cursor and return the first 1,000 rows
EXECUTE @rc = sys.sp_cursoropen
    @cur OUTPUT,
    N'
    SELECT *
    FROM AdventureWorks2012.Person.EmailAddress
        WITH (INDEX([IX_EmailAddress_EmailAddress]))
    ORDER BY EmailAddress;
    ',
    @scrollopt OUTPUT,
    @ccopt OUTPUT,
    @rowcount OUTPUT;

IF @rc <> 16 -- FastForward cursor automatically closed
BEGIN
    -- Name the cursor so we can use CURSOR_STATUS
    EXECUTE sys.sp_cursoroption
        @cur, 
        2, 
        'MyCursorName';

    -- Until the cursor auto-closes
    WHILE CURSOR_STATUS('global', 'MyCursorName') = 1
    BEGIN
        EXECUTE sys.sp_cursorfetch
            @cur,
            2,
            0,
            1000;
    END;
END;
Run Code Online (Sandbox Code Playgroud)

每个 fetch 操作最多返回 1,000 行,记住上次调用的扫描位置。