logical reads on global temp table, but not on session-level temp table The Next CEO of Stack OverflowGet minimal logging when loading data into temporary tablesCheck existence with EXISTS outperform COUNT! … Not?Which of these queries is best for performance?SQL Server - Logical Reads lowered, Execution time remained the sameMulti-statement TVF vs Inline TVF PerformanceLogical reads different when accessing the same LOB dataOPTION (RECOMPILE) is Always Faster; Why?Does IMAGE column affect query performance even if it's not included in the query?Helpful nonclustered index improved the query but raised logical readsAggregation in Outer Apply vs Left Join vs Derived tableHigh processor utilization when running a stored procedure

Is there a rule of thumb for determining the amount one should accept for of a settlement offer?

Are British MPs missing the point, with these 'Indicative Votes'?

It it possible to avoid kiwi.com's automatic online check-in and instead do it manually by yourself?

How can the PCs determine if an item is a phylactery?

Compensation for working overtime on Saturdays

Mathematica command that allows it to read my intentions

Is it OK to decorate a log book cover?

Strange use of "whether ... than ..." in official text

Is it possible to create a QR code using text?

Why does freezing point matter when picking cooler ice packs?

Why did early computer designers eschew integers?

Which acid/base does a strong base/acid react when added to a buffer solution?

Creating a script with console commands

What does this strange code stamp on my passport mean?

Why can't we say "I have been having a dog"?

Is it reasonable to ask other researchers to send me their previous grant applications?

Why was Sir Cadogan fired?

Raspberry pi 3 B with Ubuntu 18.04 server arm64: what pi version

Why do we say “un seul M” and not “une seule M” even though M is a “consonne”?

Is the offspring between a demon and a celestial possible? If so what is it called and is it in a book somewhere?

Does the Idaho Potato Commission associate potato skins with healthy eating?

What does it mean 'exit 1' for a job status after rclone sync

MT "will strike" & LXX "will watch carefully" (Gen 3:15)?

How to show a landlord what we have in savings?



logical reads on global temp table, but not on session-level temp table



The Next CEO of Stack OverflowGet minimal logging when loading data into temporary tablesCheck existence with EXISTS outperform COUNT! … Not?Which of these queries is best for performance?SQL Server - Logical Reads lowered, Execution time remained the sameMulti-statement TVF vs Inline TVF PerformanceLogical reads different when accessing the same LOB dataOPTION (RECOMPILE) is Always Faster; Why?Does IMAGE column affect query performance even if it's not included in the query?Helpful nonclustered index improved the query but raised logical readsAggregation in Outer Apply vs Left Join vs Derived tableHigh processor utilization when running a stored procedure










5















Consider the following simple MCVE:



SET STATISTICS IO, TIME OFF;
USE tempdb;

IF OBJECT_ID(N'tempdb..#t1', N'U') IS NOT NULL DROP TABLE #t1;
CREATE TABLE #t1
(
r int NOT NULL
);

IF OBJECT_ID(N'tempdb..##t1', N'U') IS NOT NULL DROP TABLE ##t1;
CREATE TABLE ##t1
(
r int NOT NULL
);

IF OBJECT_ID(N'dbo.s1', N'U') IS NOT NULL DROP TABLE dbo.s1;
CREATE TABLE dbo.s1
(
r int NOT NULL
PRIMARY KEY CLUSTERED
);

INSERT INTO dbo.s1 (r)
SELECT TOP(10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM sys.syscolumns sc1
CROSS JOIN sys.syscolumns sc2;
GO


When I run the following inserts, inserting into #t1 shows no stats I/O for the temp table. However, inserting into ##t1 does show stats I/O for the temp table.



SET STATISTICS IO, TIME ON;
GO

INSERT INTO #t1 (r)
SELECT r
FROM dbo.s1;


The stats output:



SQL Server parse and compile time: 
CPU time = 0 ms, elapsed time = 1 ms.
Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:
CPU time = 16 ms, elapsed time = 9 ms.

(10000 rows affected)


INSERT INTO ##t1 (r)
SELECT r
FROM dbo.s1;


SQL Server parse and compile time: 
CPU time = 0 ms, elapsed time = 1 ms.
Table '##t1'. Scan count 0, logical reads 10016, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:
CPU time = 47 ms, elapsed time = 45 ms.

(10000 rows affected)


Why are there so many reads on the ##temp table when I'm only inserting into it?










share|improve this question


























    5















    Consider the following simple MCVE:



    SET STATISTICS IO, TIME OFF;
    USE tempdb;

    IF OBJECT_ID(N'tempdb..#t1', N'U') IS NOT NULL DROP TABLE #t1;
    CREATE TABLE #t1
    (
    r int NOT NULL
    );

    IF OBJECT_ID(N'tempdb..##t1', N'U') IS NOT NULL DROP TABLE ##t1;
    CREATE TABLE ##t1
    (
    r int NOT NULL
    );

    IF OBJECT_ID(N'dbo.s1', N'U') IS NOT NULL DROP TABLE dbo.s1;
    CREATE TABLE dbo.s1
    (
    r int NOT NULL
    PRIMARY KEY CLUSTERED
    );

    INSERT INTO dbo.s1 (r)
    SELECT TOP(10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
    FROM sys.syscolumns sc1
    CROSS JOIN sys.syscolumns sc2;
    GO


    When I run the following inserts, inserting into #t1 shows no stats I/O for the temp table. However, inserting into ##t1 does show stats I/O for the temp table.



    SET STATISTICS IO, TIME ON;
    GO

    INSERT INTO #t1 (r)
    SELECT r
    FROM dbo.s1;


    The stats output:



    SQL Server parse and compile time: 
    CPU time = 0 ms, elapsed time = 1 ms.
    Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

    SQL Server Execution Times:
    CPU time = 16 ms, elapsed time = 9 ms.

    (10000 rows affected)


    INSERT INTO ##t1 (r)
    SELECT r
    FROM dbo.s1;


    SQL Server parse and compile time: 
    CPU time = 0 ms, elapsed time = 1 ms.
    Table '##t1'. Scan count 0, logical reads 10016, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

    SQL Server Execution Times:
    CPU time = 47 ms, elapsed time = 45 ms.

    (10000 rows affected)


    Why are there so many reads on the ##temp table when I'm only inserting into it?










    share|improve this question
























      5












      5








      5


      1






      Consider the following simple MCVE:



      SET STATISTICS IO, TIME OFF;
      USE tempdb;

      IF OBJECT_ID(N'tempdb..#t1', N'U') IS NOT NULL DROP TABLE #t1;
      CREATE TABLE #t1
      (
      r int NOT NULL
      );

      IF OBJECT_ID(N'tempdb..##t1', N'U') IS NOT NULL DROP TABLE ##t1;
      CREATE TABLE ##t1
      (
      r int NOT NULL
      );

      IF OBJECT_ID(N'dbo.s1', N'U') IS NOT NULL DROP TABLE dbo.s1;
      CREATE TABLE dbo.s1
      (
      r int NOT NULL
      PRIMARY KEY CLUSTERED
      );

      INSERT INTO dbo.s1 (r)
      SELECT TOP(10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
      FROM sys.syscolumns sc1
      CROSS JOIN sys.syscolumns sc2;
      GO


      When I run the following inserts, inserting into #t1 shows no stats I/O for the temp table. However, inserting into ##t1 does show stats I/O for the temp table.



      SET STATISTICS IO, TIME ON;
      GO

      INSERT INTO #t1 (r)
      SELECT r
      FROM dbo.s1;


      The stats output:



      SQL Server parse and compile time: 
      CPU time = 0 ms, elapsed time = 1 ms.
      Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

      SQL Server Execution Times:
      CPU time = 16 ms, elapsed time = 9 ms.

      (10000 rows affected)


      INSERT INTO ##t1 (r)
      SELECT r
      FROM dbo.s1;


      SQL Server parse and compile time: 
      CPU time = 0 ms, elapsed time = 1 ms.
      Table '##t1'. Scan count 0, logical reads 10016, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
      Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

      SQL Server Execution Times:
      CPU time = 47 ms, elapsed time = 45 ms.

      (10000 rows affected)


      Why are there so many reads on the ##temp table when I'm only inserting into it?










      share|improve this question














      Consider the following simple MCVE:



      SET STATISTICS IO, TIME OFF;
      USE tempdb;

      IF OBJECT_ID(N'tempdb..#t1', N'U') IS NOT NULL DROP TABLE #t1;
      CREATE TABLE #t1
      (
      r int NOT NULL
      );

      IF OBJECT_ID(N'tempdb..##t1', N'U') IS NOT NULL DROP TABLE ##t1;
      CREATE TABLE ##t1
      (
      r int NOT NULL
      );

      IF OBJECT_ID(N'dbo.s1', N'U') IS NOT NULL DROP TABLE dbo.s1;
      CREATE TABLE dbo.s1
      (
      r int NOT NULL
      PRIMARY KEY CLUSTERED
      );

      INSERT INTO dbo.s1 (r)
      SELECT TOP(10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
      FROM sys.syscolumns sc1
      CROSS JOIN sys.syscolumns sc2;
      GO


      When I run the following inserts, inserting into #t1 shows no stats I/O for the temp table. However, inserting into ##t1 does show stats I/O for the temp table.



      SET STATISTICS IO, TIME ON;
      GO

      INSERT INTO #t1 (r)
      SELECT r
      FROM dbo.s1;


      The stats output:



      SQL Server parse and compile time: 
      CPU time = 0 ms, elapsed time = 1 ms.
      Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

      SQL Server Execution Times:
      CPU time = 16 ms, elapsed time = 9 ms.

      (10000 rows affected)


      INSERT INTO ##t1 (r)
      SELECT r
      FROM dbo.s1;


      SQL Server parse and compile time: 
      CPU time = 0 ms, elapsed time = 1 ms.
      Table '##t1'. Scan count 0, logical reads 10016, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
      Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

      SQL Server Execution Times:
      CPU time = 47 ms, elapsed time = 45 ms.

      (10000 rows affected)


      Why are there so many reads on the ##temp table when I'm only inserting into it?







      sql-server sql-server-2016 temporary-tables






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 2 hours ago









      Max VernonMax Vernon

      52k13114230




      52k13114230




















          1 Answer
          1






          active

          oldest

          votes


















          4














          Minimal logging is not being used when using INSERT INTO and global temp tables



          Inserting one million rows in a global temp table by using INSERT INTO



          INSERT INTO ##t1 (r)
          SELECT top(1000000) s1.r
          FROM dbo.s1
          CROSS APPLY dbo.s1 S2;


          When running SELECT * FROM fn_dblog(NULL, NULL) while the above query is executing, ~1M rows are returned.



          enter image description here



          One LOP_INSERT_ROW operation for each row + other
          log data.




          The same insert on a local temp table



          INSERT INTO #t1 (r)
          SELECT top(1000000) s1.r
          FROM dbo.s1
          CROSS APPLY dbo.s1 S2;


          Only going up to 700 rows returned by SELECT * FROM fn_dblog(NULL, NULL)



          enter image description here



          Minimal logging




          Inserting one million rows in a global temp table by using SELECT INTO



          SELECT top(1000000) s1.r
          INTO ##t2
          FROM dbo.s1
          CROSS APPLY dbo.s1 S2;


          enter image description here



          SELECT INTO a global temp table with 10k records



          SELECT s1.r
          INTO ##t2
          FROM dbo.s1;


          Time and IO Statistics



          SQL Server parse and compile time: 
          CPU time = 0 ms, elapsed time = 0 ms.
          Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

          SQL Server Execution Times:
          CPU time = 16 ms, elapsed time = 10 ms.
          SQL Server parse and compile time:
          CPU time = 0 ms, elapsed time = 0 ms.



          Based on this blogpost we can add TABLOCK to initiate minimal logging on a heap table



          INSERT INTO ##t1 WITH(TABLOCK) (r)
          SELECT s1.r
          FROM dbo.s1


          Low logical reads



          Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

          (10000 rows affected)



          Part of an answer by @PaulWhite on how to achieve minimal logging on temporary tables




          No. Local temporary tables (#temp) are private to the creating
          session, so a table lock hint is not required. A table lock hint would
          be required for a global temporary table (##temp) or a regular table
          (dbo.temp) created in tempdb, because these can be accessed from
          multiple sessions.




          Creating a regular table to test this:



          CREATE TABLE dbo.bla
          (
          r int NOT NULL
          );


          Filling it up with 1M records



          INSERT INTO bla 
          SELECT top(1000000)s1.r
          FROM dbo.s1
          CROSS APPLY dbo.s1 S2;


          >1M logical reads on this table



          Table 's1'. Scan count 17, logical reads 155, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
          Table 'bla'. Scan count 0, logical reads 1001607, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
          Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.



          Paul White's answer explaining the logical reads reported on the global temp table




          Generally, logical reads are reported for the target table when the
          insert is not minimally logged.



          These logical reads are associated with finding a place in the
          existing structure to add the new rows. Minimally-logged inserts use
          the bulk-loading mechanism, which allocates whole new pages/extents
          (and so does not need to read the target structure in the same way).





          Conclusion



          The conclusion being that the INSERT INTO is not able to use minimal logging, resulting in logging every inserted row individually in the log file of tempdb when used in combination with a global temp table / normal table.
          Whereas the local temp table/ SELECT INTO/ INSERT INTO ... WITH(TABLOCK) is able to use minimal logging.






          share|improve this answer

























            Your Answer








            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "182"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f233689%2flogical-reads-on-global-temp-table-but-not-on-session-level-temp-table%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            4














            Minimal logging is not being used when using INSERT INTO and global temp tables



            Inserting one million rows in a global temp table by using INSERT INTO



            INSERT INTO ##t1 (r)
            SELECT top(1000000) s1.r
            FROM dbo.s1
            CROSS APPLY dbo.s1 S2;


            When running SELECT * FROM fn_dblog(NULL, NULL) while the above query is executing, ~1M rows are returned.



            enter image description here



            One LOP_INSERT_ROW operation for each row + other
            log data.




            The same insert on a local temp table



            INSERT INTO #t1 (r)
            SELECT top(1000000) s1.r
            FROM dbo.s1
            CROSS APPLY dbo.s1 S2;


            Only going up to 700 rows returned by SELECT * FROM fn_dblog(NULL, NULL)



            enter image description here



            Minimal logging




            Inserting one million rows in a global temp table by using SELECT INTO



            SELECT top(1000000) s1.r
            INTO ##t2
            FROM dbo.s1
            CROSS APPLY dbo.s1 S2;


            enter image description here



            SELECT INTO a global temp table with 10k records



            SELECT s1.r
            INTO ##t2
            FROM dbo.s1;


            Time and IO Statistics



            SQL Server parse and compile time: 
            CPU time = 0 ms, elapsed time = 0 ms.
            Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

            SQL Server Execution Times:
            CPU time = 16 ms, elapsed time = 10 ms.
            SQL Server parse and compile time:
            CPU time = 0 ms, elapsed time = 0 ms.



            Based on this blogpost we can add TABLOCK to initiate minimal logging on a heap table



            INSERT INTO ##t1 WITH(TABLOCK) (r)
            SELECT s1.r
            FROM dbo.s1


            Low logical reads



            Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

            (10000 rows affected)



            Part of an answer by @PaulWhite on how to achieve minimal logging on temporary tables




            No. Local temporary tables (#temp) are private to the creating
            session, so a table lock hint is not required. A table lock hint would
            be required for a global temporary table (##temp) or a regular table
            (dbo.temp) created in tempdb, because these can be accessed from
            multiple sessions.




            Creating a regular table to test this:



            CREATE TABLE dbo.bla
            (
            r int NOT NULL
            );


            Filling it up with 1M records



            INSERT INTO bla 
            SELECT top(1000000)s1.r
            FROM dbo.s1
            CROSS APPLY dbo.s1 S2;


            >1M logical reads on this table



            Table 's1'. Scan count 17, logical reads 155, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
            Table 'bla'. Scan count 0, logical reads 1001607, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
            Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.



            Paul White's answer explaining the logical reads reported on the global temp table




            Generally, logical reads are reported for the target table when the
            insert is not minimally logged.



            These logical reads are associated with finding a place in the
            existing structure to add the new rows. Minimally-logged inserts use
            the bulk-loading mechanism, which allocates whole new pages/extents
            (and so does not need to read the target structure in the same way).





            Conclusion



            The conclusion being that the INSERT INTO is not able to use minimal logging, resulting in logging every inserted row individually in the log file of tempdb when used in combination with a global temp table / normal table.
            Whereas the local temp table/ SELECT INTO/ INSERT INTO ... WITH(TABLOCK) is able to use minimal logging.






            share|improve this answer





























              4














              Minimal logging is not being used when using INSERT INTO and global temp tables



              Inserting one million rows in a global temp table by using INSERT INTO



              INSERT INTO ##t1 (r)
              SELECT top(1000000) s1.r
              FROM dbo.s1
              CROSS APPLY dbo.s1 S2;


              When running SELECT * FROM fn_dblog(NULL, NULL) while the above query is executing, ~1M rows are returned.



              enter image description here



              One LOP_INSERT_ROW operation for each row + other
              log data.




              The same insert on a local temp table



              INSERT INTO #t1 (r)
              SELECT top(1000000) s1.r
              FROM dbo.s1
              CROSS APPLY dbo.s1 S2;


              Only going up to 700 rows returned by SELECT * FROM fn_dblog(NULL, NULL)



              enter image description here



              Minimal logging




              Inserting one million rows in a global temp table by using SELECT INTO



              SELECT top(1000000) s1.r
              INTO ##t2
              FROM dbo.s1
              CROSS APPLY dbo.s1 S2;


              enter image description here



              SELECT INTO a global temp table with 10k records



              SELECT s1.r
              INTO ##t2
              FROM dbo.s1;


              Time and IO Statistics



              SQL Server parse and compile time: 
              CPU time = 0 ms, elapsed time = 0 ms.
              Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

              SQL Server Execution Times:
              CPU time = 16 ms, elapsed time = 10 ms.
              SQL Server parse and compile time:
              CPU time = 0 ms, elapsed time = 0 ms.



              Based on this blogpost we can add TABLOCK to initiate minimal logging on a heap table



              INSERT INTO ##t1 WITH(TABLOCK) (r)
              SELECT s1.r
              FROM dbo.s1


              Low logical reads



              Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

              (10000 rows affected)



              Part of an answer by @PaulWhite on how to achieve minimal logging on temporary tables




              No. Local temporary tables (#temp) are private to the creating
              session, so a table lock hint is not required. A table lock hint would
              be required for a global temporary table (##temp) or a regular table
              (dbo.temp) created in tempdb, because these can be accessed from
              multiple sessions.




              Creating a regular table to test this:



              CREATE TABLE dbo.bla
              (
              r int NOT NULL
              );


              Filling it up with 1M records



              INSERT INTO bla 
              SELECT top(1000000)s1.r
              FROM dbo.s1
              CROSS APPLY dbo.s1 S2;


              >1M logical reads on this table



              Table 's1'. Scan count 17, logical reads 155, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
              Table 'bla'. Scan count 0, logical reads 1001607, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
              Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.



              Paul White's answer explaining the logical reads reported on the global temp table




              Generally, logical reads are reported for the target table when the
              insert is not minimally logged.



              These logical reads are associated with finding a place in the
              existing structure to add the new rows. Minimally-logged inserts use
              the bulk-loading mechanism, which allocates whole new pages/extents
              (and so does not need to read the target structure in the same way).





              Conclusion



              The conclusion being that the INSERT INTO is not able to use minimal logging, resulting in logging every inserted row individually in the log file of tempdb when used in combination with a global temp table / normal table.
              Whereas the local temp table/ SELECT INTO/ INSERT INTO ... WITH(TABLOCK) is able to use minimal logging.






              share|improve this answer



























                4












                4








                4







                Minimal logging is not being used when using INSERT INTO and global temp tables



                Inserting one million rows in a global temp table by using INSERT INTO



                INSERT INTO ##t1 (r)
                SELECT top(1000000) s1.r
                FROM dbo.s1
                CROSS APPLY dbo.s1 S2;


                When running SELECT * FROM fn_dblog(NULL, NULL) while the above query is executing, ~1M rows are returned.



                enter image description here



                One LOP_INSERT_ROW operation for each row + other
                log data.




                The same insert on a local temp table



                INSERT INTO #t1 (r)
                SELECT top(1000000) s1.r
                FROM dbo.s1
                CROSS APPLY dbo.s1 S2;


                Only going up to 700 rows returned by SELECT * FROM fn_dblog(NULL, NULL)



                enter image description here



                Minimal logging




                Inserting one million rows in a global temp table by using SELECT INTO



                SELECT top(1000000) s1.r
                INTO ##t2
                FROM dbo.s1
                CROSS APPLY dbo.s1 S2;


                enter image description here



                SELECT INTO a global temp table with 10k records



                SELECT s1.r
                INTO ##t2
                FROM dbo.s1;


                Time and IO Statistics



                SQL Server parse and compile time: 
                CPU time = 0 ms, elapsed time = 0 ms.
                Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

                SQL Server Execution Times:
                CPU time = 16 ms, elapsed time = 10 ms.
                SQL Server parse and compile time:
                CPU time = 0 ms, elapsed time = 0 ms.



                Based on this blogpost we can add TABLOCK to initiate minimal logging on a heap table



                INSERT INTO ##t1 WITH(TABLOCK) (r)
                SELECT s1.r
                FROM dbo.s1


                Low logical reads



                Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

                (10000 rows affected)



                Part of an answer by @PaulWhite on how to achieve minimal logging on temporary tables




                No. Local temporary tables (#temp) are private to the creating
                session, so a table lock hint is not required. A table lock hint would
                be required for a global temporary table (##temp) or a regular table
                (dbo.temp) created in tempdb, because these can be accessed from
                multiple sessions.




                Creating a regular table to test this:



                CREATE TABLE dbo.bla
                (
                r int NOT NULL
                );


                Filling it up with 1M records



                INSERT INTO bla 
                SELECT top(1000000)s1.r
                FROM dbo.s1
                CROSS APPLY dbo.s1 S2;


                >1M logical reads on this table



                Table 's1'. Scan count 17, logical reads 155, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
                Table 'bla'. Scan count 0, logical reads 1001607, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
                Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.



                Paul White's answer explaining the logical reads reported on the global temp table




                Generally, logical reads are reported for the target table when the
                insert is not minimally logged.



                These logical reads are associated with finding a place in the
                existing structure to add the new rows. Minimally-logged inserts use
                the bulk-loading mechanism, which allocates whole new pages/extents
                (and so does not need to read the target structure in the same way).





                Conclusion



                The conclusion being that the INSERT INTO is not able to use minimal logging, resulting in logging every inserted row individually in the log file of tempdb when used in combination with a global temp table / normal table.
                Whereas the local temp table/ SELECT INTO/ INSERT INTO ... WITH(TABLOCK) is able to use minimal logging.






                share|improve this answer















                Minimal logging is not being used when using INSERT INTO and global temp tables



                Inserting one million rows in a global temp table by using INSERT INTO



                INSERT INTO ##t1 (r)
                SELECT top(1000000) s1.r
                FROM dbo.s1
                CROSS APPLY dbo.s1 S2;


                When running SELECT * FROM fn_dblog(NULL, NULL) while the above query is executing, ~1M rows are returned.



                enter image description here



                One LOP_INSERT_ROW operation for each row + other
                log data.




                The same insert on a local temp table



                INSERT INTO #t1 (r)
                SELECT top(1000000) s1.r
                FROM dbo.s1
                CROSS APPLY dbo.s1 S2;


                Only going up to 700 rows returned by SELECT * FROM fn_dblog(NULL, NULL)



                enter image description here



                Minimal logging




                Inserting one million rows in a global temp table by using SELECT INTO



                SELECT top(1000000) s1.r
                INTO ##t2
                FROM dbo.s1
                CROSS APPLY dbo.s1 S2;


                enter image description here



                SELECT INTO a global temp table with 10k records



                SELECT s1.r
                INTO ##t2
                FROM dbo.s1;


                Time and IO Statistics



                SQL Server parse and compile time: 
                CPU time = 0 ms, elapsed time = 0 ms.
                Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

                SQL Server Execution Times:
                CPU time = 16 ms, elapsed time = 10 ms.
                SQL Server parse and compile time:
                CPU time = 0 ms, elapsed time = 0 ms.



                Based on this blogpost we can add TABLOCK to initiate minimal logging on a heap table



                INSERT INTO ##t1 WITH(TABLOCK) (r)
                SELECT s1.r
                FROM dbo.s1


                Low logical reads



                Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

                (10000 rows affected)



                Part of an answer by @PaulWhite on how to achieve minimal logging on temporary tables




                No. Local temporary tables (#temp) are private to the creating
                session, so a table lock hint is not required. A table lock hint would
                be required for a global temporary table (##temp) or a regular table
                (dbo.temp) created in tempdb, because these can be accessed from
                multiple sessions.




                Creating a regular table to test this:



                CREATE TABLE dbo.bla
                (
                r int NOT NULL
                );


                Filling it up with 1M records



                INSERT INTO bla 
                SELECT top(1000000)s1.r
                FROM dbo.s1
                CROSS APPLY dbo.s1 S2;


                >1M logical reads on this table



                Table 's1'. Scan count 17, logical reads 155, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
                Table 'bla'. Scan count 0, logical reads 1001607, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
                Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.



                Paul White's answer explaining the logical reads reported on the global temp table




                Generally, logical reads are reported for the target table when the
                insert is not minimally logged.



                These logical reads are associated with finding a place in the
                existing structure to add the new rows. Minimally-logged inserts use
                the bulk-loading mechanism, which allocates whole new pages/extents
                (and so does not need to read the target structure in the same way).





                Conclusion



                The conclusion being that the INSERT INTO is not able to use minimal logging, resulting in logging every inserted row individually in the log file of tempdb when used in combination with a global temp table / normal table.
                Whereas the local temp table/ SELECT INTO/ INSERT INTO ... WITH(TABLOCK) is able to use minimal logging.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited 28 mins ago

























                answered 1 hour ago









                Randi VertongenRandi Vertongen

                4,201924




                4,201924



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Database Administrators Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f233689%2flogical-reads-on-global-temp-table-but-not-on-session-level-temp-table%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    कुँवर स्रोत दिक्चालन सूची"कुँवर""राणा कुँवरके वंशावली"

                    Why is a white electrical wire connected to 2 black wires?How to wire a light fixture with 3 white wires in box?How should I wire a ceiling fan when there's only three wires in the box?Two white, two black, two ground, and red wire in ceiling box connected to switchWhy is there a white wire connected to multiple black wires in my light box?How to wire a light with two white wires and one black wireReplace light switch connected to a power outlet with dimmer - two black wires to one black and redHow to wire a light with multiple black/white/green wires from the ceiling?Ceiling box has 2 black and white wires but fan/ light only has 1 of eachWhy neutral wire connected to load wire?Switch with 2 black, 2 white, 2 ground and 1 red wire connected to ceiling light and a receptacle?

                    चैत्य भूमि चित्र दीर्घा सन्दर्भ बाहरी कडियाँ दिक्चालन सूची"Chaitya Bhoomi""Chaitya Bhoomi: Statue of Equality in India""Dadar Chaitya Bhoomi: Statue of Equality in India""Ambedkar memorial: Centre okays transfer of Indu Mill land"चैत्यभमि