복붙노트

[SQL] SQL Server 테이블에서 n은 임의의 행을 선택

SQL

SQL Server 테이블에서 n은 임의의 행을 선택

나는 거기에 50,000에 대한 행이있는 SQL Server 테이블을 가지고있다. 나는 무작위로 해당 행의 5,000에 대한 선택합니다. 나는 그 테이블에서 선택 후, 「랜덤 번호 "열이있는 임시 테이블을 생성하는 임시 테이블을 통해 반복, 그에 내 테이블을 복사하고 RAND ()와 각 행을 업데이트하고, 복잡한 방법을 생각했습니다 경우 임의을 번호 열 <0.1. 나는 가능하면 하나의 문에, 그것을 할 수있는 간단한 방법을 찾고 있어요.

이 문서에서는 NEWID () 함수를 사용하는 것이 좋습니다. 그건 외모는 유망하지만, 나는 확실하게 행의 일정 비율을 선택할 수있는 방법을 볼 수 없습니다.

누구나 지금이 전에합니까? 어떤 아이디어?

해결법

  1. ==============================

    1.

    select top 10 percent * from [yourtable] order by newid()
    

    큰 테이블에 관한 "순수한 쓰레기"의견에 대응 : 당신은 성능 향상을 위해 다음과 같이 그것을 할 수 있습니다.

    select  * from [yourtable] where [yourPk] in 
    (select top 10 percent [yourPk] from [yourtable] order by newid())
    

    이 비용은 값의 키 스캔 할 것이다 플러스는 작은 비율의 선택에 큰 테이블에 합리적이어야한다 비용을 가입 할 수 있습니다.

  2. ==============================

    2.필요에 따라 TABLESAMPLE은 거의 무작위 더 나은 성능으로 얻을 것이다. 이것은 MS SQL 서버 2005 이상에서 사용할 수 있습니다.

    필요에 따라 TABLESAMPLE은 거의 무작위 더 나은 성능으로 얻을 것이다. 이것은 MS SQL 서버 2005 이상에서 사용할 수 있습니다.

    TABLESAMPLE 임의의 페이지 대신 임의의 행에서 데이터를 반환하기 때문에 심지어는 반환하지 않습니다 데이터를 검색하지 않습니다.

    매우 큰 테이블에 나는 테스트

    select top 1 percent * from [tablename] order by newid()
    

    20 분 이상 걸렸다.

    select * from [tablename] tablesample(1 percent)
    

    2 분했다.

    성능 또한 NEWID하지 않습니다 반면 () TABLESAMPLE에 작은 샘플을 향상시킬 수 있습니다.

    이것은 NEWID () 메소드로 임의 아니라는 것을 염두에 두어야하지만, 당신에게 알맞은 샘플링을 줄 것이다하시기 바랍니다.

    은 MSDN 페이지를 참조하십시오.

  3. ==============================

    3.NEWID () 의지 작업에 의해 / 위해, 그러나 모든 행에 대한 ID를 생성하기 때문에 큰 결과 세트 매우 비싼 다음 종류의 그 것이다.

    NEWID () 의지 작업에 의해 / 위해, 그러나 모든 행에 대한 ID를 생성하기 때문에 큰 결과 세트 매우 비싼 다음 종류의 그 것이다.

    TABLESAMPLE ()는 성능면에서 좋다, 그러나 당신은 결과의 응집을 (페이지의 모든 행이 반환됩니다) 얻을 것이다.

    더 나은 수행하는 진정한 무작위 샘플 들어, 가장 좋은 방법은 임의로 행을 필터링하는 것입니다. 나는 TABLESAMPLE을 사용하여 결과 세트를 제한은 SQL Server 온라인 문서의 다음 코드 샘플을 발견 :

    1,000,000 행이 테이블에 대해 실행하면, 여기에 내 결과는 다음과 같습니다

    SET STATISTICS TIME ON
    SET STATISTICS IO ON
    
    /* newid()
       rows returned: 10000
       logical reads: 3359
       CPU time: 3312 ms
       elapsed time = 3359 ms
    */
    SELECT TOP 1 PERCENT Number
    FROM Numbers
    ORDER BY newid()
    
    /* TABLESAMPLE
       rows returned: 9269 (varies)
       logical reads: 32
       CPU time: 0 ms
       elapsed time: 5 ms
    */
    SELECT Number
    FROM Numbers
    TABLESAMPLE (1 PERCENT)
    
    /* Filter
       rows returned: 9994 (varies)
       logical reads: 3359
       CPU time: 641 ms
       elapsed time: 627 ms
    */    
    SELECT Number
    FROM Numbers
    WHERE 0.01 >= CAST(CHECKSUM(NEWID(), Number) & 0x7fffffff AS float) 
                  / CAST (0x7fffffff AS int)
    
    SET STATISTICS IO OFF
    SET STATISTICS TIME OFF
    

    당신이 TABLESAMPLE을 사용하여 멀리 얻을 수 있다면, 그것은 당신에게 최상의 성능을 제공 할 것입니다. 그렇지 NEWID () / 필터 방법을 사용한다. 당신은 큰 결과 집합이있는 경우로 NEWID () / 순서는 최후의 수단이어야한다.

  4. ==============================

    4.MSDN에 큰 테이블에서 임의로 행을 선택하면 간단하고 잘 관절 솔루션 즉 주소 대규모 성능 문제가 있습니다.

    MSDN에 큰 테이블에서 임의로 행을 선택하면 간단하고 잘 관절 솔루션 즉 주소 대규모 성능 문제가 있습니다.

      SELECT * FROM Table1
      WHERE (ABS(CAST(
      (BINARY_CHECKSUM(*) *
      RAND()) as int)) % 100) < 10
    
  5. ==============================

    5.이 링크는 행 1, 7, 13 수백만 테이블 ORDERBY (NEWID ())와 다른 방법 사이의 흥미로운 비교가 있습니다.

    이 링크는 행 1, 7, 13 수백만 테이블 ORDERBY (NEWID ())와 다른 방법 사이의 흥미로운 비교가 있습니다.

    임의의 행을 선택하는 방법에 대한 질문은 토론 그룹에 질문 할 때 종종는 NEWID 쿼리 제안한다; 그것은 간단하고 작은 테이블 매우 잘 작동합니다.

    SELECT TOP 10 PERCENT *
      FROM Table1
      ORDER BY NEWID()
    

    그러나 NEWID 쿼리는 큰 테이블을 위해 그것을 사용하는 큰 단점이있다. ORDER BY 절은 테이블의 모든 행들이 정렬되어있는 tempdb의 데이터베이스에 복사되도록합니다. 이 두 가지 문제가 발생합니다

    당신은 무엇이 필요 tempdb를 사용하지 않습니다 테이블이 커질수록 훨씬 느린받지 않습니다 그 무작위 행을 선택하는 방법입니다. 여기에 그 작업을 수행하는 방법에 대한 새로운 아이디어입니다 :

    SELECT * FROM Table1
      WHERE (ABS(CAST(
      (BINARY_CHECKSUM(*) *
      RAND()) as int)) % 100) < 10
    

    이 쿼리의 기본 개념은 우리가 테이블의 각 행에 대해 0에서 99 사이의 임의의 숫자를 생성 한 다음 그 난수 지정된 퍼센트의 값보다 작은 그 모든 행을 선택하는 것이 좋습니다 것입니다. 이 예제에서, 우리는 무작위로 선택된 행의 약 10 %를 원하는; 그러므로, 우리는 누구의 임의의 숫자 10 미만의 모든 행을 선택합니다.

    MSDN에서 전체 기사를 읽어 보시기 바랍니다.

  6. ==============================

    6.(OP는 달리) 당신이 (체크섬 접근을 어렵게) 레코드의 특정 번호를 필요 TABLESAMPLE은 그 자체로 제공하는 것보다 더 무작위 표본을 원하고, 또한 CHECKSUM보다 더 속도를 원한다면, 당신은의 합병으로 수행 할 수 있습니다 TABLESAMPLE 및 NEWID ()이 같은 방법 :

    (OP는 달리) 당신이 (체크섬 접근을 어렵게) 레코드의 특정 번호를 필요 TABLESAMPLE은 그 자체로 제공하는 것보다 더 무작위 표본을 원하고, 또한 CHECKSUM보다 더 속도를 원한다면, 당신은의 합병으로 수행 할 수 있습니다 TABLESAMPLE 및 NEWID ()이 같은 방법 :

    DECLARE @sampleCount int = 50
    SET STATISTICS TIME ON
    
    SELECT TOP (@sampleCount) * 
    FROM [yourtable] TABLESAMPLE(10 PERCENT)
    ORDER BY NEWID()
    
    SET STATISTICS TIME OFF
    

    내 경우에는이 가장 간단 임의성 사이의 타협 (이것은 정말 아니다 내가 아는)과 속도입니다. TABLESAMPLE 비율 (또는 행) 적절한 바리 - 높은 비율, 더 무작위 샘플을하지만, 속도가 떨어져 선형 하락을 기대합니다. (주 TABLESAMPLE 변수를 채택하지 않도록)

  7. ==============================

    7.그냥 임의의 숫자에 의해 테이블을 주문하고 TOP을 사용하여 첫 번째 5,000 행을 구하십시오.

    그냥 임의의 숫자에 의해 테이블을 주문하고 TOP을 사용하여 첫 번째 5,000 행을 구하십시오.

    SELECT TOP 5000 * FROM [Table] ORDER BY newid();
    

    최신 정보

    다만 그것을 시도하지 않고 새로운 ID () 호출은 충분하다 - 캐스트 및 모든 수학의 모든 필요를.

  8. ==============================

    8.이 날 NEWID ()의 비용없이 제대로 임의 결과를 제공하기에 보이는 초기 종자 아이디어와 체크섬 (checksum)의 조합이다 :

    이 날 NEWID ()의 비용없이 제대로 임의 결과를 제공하기에 보이는 초기 종자 아이디어와 체크섬 (checksum)의 조합이다 :

    SELECT TOP [number] 
    FROM table_name
    ORDER BY RAND(CHECKSUM(*) * RAND())
    
  9. ==============================

    9.MySQL의에서이 작업을 수행 할 수 있습니다 :

    MySQL의에서이 작업을 수행 할 수 있습니다 :

    SELECT `PRIMARY_KEY`, rand() FROM table ORDER BY rand() LIMIT 5000;
    
  10. ==============================

    10.확실히 대답이 변화를 아직 보지 못했다. 나는 동일한 행 세트마다 선택, 초기 씨앗 주어, 내가 필요한 추가적인 제약이 있었다.

    확실히 대답이 변화를 아직 보지 못했다. 나는 동일한 행 세트마다 선택, 초기 씨앗 주어, 내가 필요한 추가적인 제약이 있었다.

    MS SQL의 경우 :

    최소 예 :

    select top 10 percent *
    from table_name
    order by rand(checksum(*))
    

    정규화 실행 시간 : 1.00

    변경 () 예 :

    select top 10 percent *
    from table_name
    order by newid()
    

    정규화 실행 시간 : 1.02

    NEWID ()가 하찮게 느린 랜드보다 (체크섬 (*)), 당신은 큰 레코드 세트에 대해 그것을 사용하려는되지 않을 수도 있습니다.

    초기 씨앗과 선택 :

    declare @seed int
    set @seed = Year(getdate()) * month(getdate()) /* any other initial seed here */
    
    select top 10 percent *
    from table_name
    order by rand(checksum(*) % @seed) /* any other math function here */
    

    당신이 씨 주어진 동일한 세트를 선택해야하는 경우이 작동하는 것 같다.

  11. ==============================

    11.이 시도:

    이 시도:

    SELECT TOP 10 Field1, ..., FieldN
    FROM Table1
    ORDER BY NEWID()
    
  12. ==============================

    12.그것은 () 절, 그래서이 솔루션은 내부 쿼리를 요구 곳에서 사용할 수 없습니다 NEWID 나타납니다 :

    그것은 () 절, 그래서이 솔루션은 내부 쿼리를 요구 곳에서 사용할 수 없습니다 NEWID 나타납니다 :

    SELECT *
    FROM (
        SELECT *, ABS(CHECKSUM(NEWID())) AS Rnd
        FROM MyTable
    ) vw
    WHERE Rnd % 100 < 10        --10%
    
  13. ==============================

    13.나는 서브 쿼리에서 사용 된 그것은 나에게 하위 쿼리에서 같은 행을 반환

    나는 서브 쿼리에서 사용 된 그것은 나에게 하위 쿼리에서 같은 행을 반환

     SELECT  ID ,
                ( SELECT TOP 1
                            ImageURL
                  FROM      SubTable 
                  ORDER BY  NEWID()
                ) AS ImageURL,
                GETUTCDATE() ,
                1
        FROM    Mytable
    

    그럼 여기서 상위에 나타난 변수를 포함 해결할

    SELECT  ID ,
                ( SELECT TOP 1
                            ImageURL
                  FROM      SubTable 
                  Where Mytable.ID>0
                  ORDER BY  NEWID()
                ) AS ImageURL,
                GETUTCDATE() ,
                1
        FROM    Mytable
    

    WHERE 조건을 참고

  14. ==============================

    14.사용중인 서버 쪽 처리 언어 (예 : PHP, .NET 등)을 지정하지만 PHP를의 경우, 필요한 수의 (또는 모든 레코드) 대신 쿼리 사용 PHP의 셔플 기능을 무작위 화의 잡아되지 않습니다. .NET은 동등한 기능이 있는지 모르겠어요하지만 그를 사용 않는 경우에 당신이 사용하는 경우 .NET

    사용중인 서버 쪽 처리 언어 (예 : PHP, .NET 등)을 지정하지만 PHP를의 경우, 필요한 수의 (또는 모든 레코드) 대신 쿼리 사용 PHP의 셔플 기능을 무작위 화의 잡아되지 않습니다. .NET은 동등한 기능이 있는지 모르겠어요하지만 그를 사용 않는 경우에 당신이 사용하는 경우 .NET

    ORDER BY RAND ()는 관련된 레코드 수에 따라 상당한 성능 저하를 가질 수 있습니다.

  15. ==============================

    15.이것은 나를 위해 작동합니다 :

    이것은 나를 위해 작동합니다 :

    SELECT * FROM table_name
    ORDER BY RANDOM()
    LIMIT [number]
    
  16. from https://stackoverflow.com/questions/848872/select-n-random-rows-from-sql-server-table by cc-by-sa and MIT license