After Restoring Log Shipping to Secondary Server, First Stored Procedure Execution is SlowSQL Server clears plan cache and execution stats periodicallyDifferences Between Setting Up Transaction Log Shipping through Wizard vs ScriptsSQL Server Log shipping standby db stuck restoringLog Shipping -Monitor Server Down - Copying happening but not restoring on secondaryAlter of stored procedure and execution performanceLog Shipping SQL Server 2012Clearing Log Shipping config Secondary server inaccessibleProblem Configuring Log Shipping for DR ServerRestoring Job failed with error 'Could not find a log backup file that could be applied' on Log Shipping in SQL Server (Secondary)?Log Shipping: Bulk Remove Alerts of already deleted primary and secondary databasesSQL server log shipping - dry-run data modification script on secondary then resume log shippingTransaction Log Shipping Primary Server Status not Shown on Secondary Monitoring Server

Image processing: Removal of two spots in fundus images

Does Nitrogen inside commercial airliner wheels prevent blowouts on touchdown?

Why were helmets and other body armour not commonplace in the 1800s?

Plot twist where the antagonist wins

Flying domestically in the US, is my State Issued ID all I need to get past security?

Statue View: 2, 3, 5, 7

Does the unit of measure matter when you are solving for the diameter of a circumference?

Adding spaces to string based on list

Why does a perfectly-identical repetition of a drawing command given within an earlier loop 𝘯𝘰𝘵 produce exactly the same line?

What is memelemum?

How do Human Traits Work?

Are these reasonable traits for someone with autism?

When and what was the first 3D acceleration device ever released?

Why doesn't the Earth accelerate towards the Moon?

Looking for a soft substance that doesn't dissolve underwater

What are these arcade games in Ghostbusters 1984?

Cipher Block Chaining - How do you change the plaintext of all blocks?

Where have Brexit voters gone?

Employer asking for online access to bank account - Is this a scam?

Simple function that simulates survey results based on sample size and probability

Why are C64 games inconsistent with which joystick port they use?

Is it possible to play as a necromancer skeleton?

Binary Search in C++17

Crossing US border with music files I'm legally allowed to possess



After Restoring Log Shipping to Secondary Server, First Stored Procedure Execution is Slow


SQL Server clears plan cache and execution stats periodicallyDifferences Between Setting Up Transaction Log Shipping through Wizard vs ScriptsSQL Server Log shipping standby db stuck restoringLog Shipping -Monitor Server Down - Copying happening but not restoring on secondaryAlter of stored procedure and execution performanceLog Shipping SQL Server 2012Clearing Log Shipping config Secondary server inaccessibleProblem Configuring Log Shipping for DR ServerRestoring Job failed with error 'Could not find a log backup file that could be applied' on Log Shipping in SQL Server (Secondary)?Log Shipping: Bulk Remove Alerts of already deleted primary and secondary databasesSQL server log shipping - dry-run data modification script on secondary then resume log shippingTransaction Log Shipping Primary Server Status not Shown on Secondary Monitoring Server






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








7















We've set up log shipping to a secondary SQL server on Standby/ Read-Only to offload all SSRS report generation.

This works fine within the restrictions imposed by:



  1. Kicking out the user during the transaction log restore (we got around this by setting up multiple instances and restoring the most recent transaction logs using a round-robin schedule)

  2. The data being out of date by, at most, the time-frame indicated by the scheduled transaction log backup/ restore job.

Unfortunately, the first time any/ all stored procedure are run, after the transaction log was restored, it takes a much longer time to complete than normal. All subsequent executions of that same stored procedure complete within the expected time. If we then execute another stored procedure, the first time it is slow and all subsequent executions complete in the expected time.



For reference, the difference in execution is ~00:02 normally compared to ~01:00 on the first run.



I assume this has something to do with either the server execution statistics or the stored procedure parameter sniffing/ stored execution plan.

Is there any way to get around this issue? Or is this inherent to the transaction log restore?



If it was just the very first execution of any stored procedure we could get around this easily by executing any stored procedure upon restore, but it appears to affect the first time all stored procedures are executed.



I tried running count( * ) on the 11 tables the stored procedure I'm using for testing touches. The first run took 00:32, and subsequent count(*) took 00:00. Unfortunately, this did not have any impact on the first run of the stored procedure.



I don't see any results on either my primary or secondary servers for is_temporary stats, either before or after execution of a stored procedure.



I'm currently on SQL Server 2012


Query Exection Plan:
The query execution plan at first glance appears significantly different, however, upon saving the execution plan and opening the .sqlplan file generated they are exactly the same. The difference appears to be coming from the different versions of SSMS I am using, 2014 on the primary server and 2018 on the secondary. When viewing the execution plan on the secondary it shows underneath every node's % and time cost ### of ### (##%) - neither those numbers, nor the actual execution plan change upon further executions.
I also included client statistics and they show almost exactly the same, the only difference being the primary server executes with 1.4 seconds of Wait time on server replies and the secondary takes 81.3 seconds.

I do see a large number of PAGEIOLATCH_SH locks from the first execution, as you predicted:



diff after first exec vs diff after second exec
waiting_tasks_count 10903 918
wait_time_ms 411129 12768


One of the odd things about this situation, is, except for the round-robin multiple instances part of the setup we already have our production SSRS server reading from a standby/ read-only database that is fed by periodic transaction logs and do not experience these slow downs on the first execution of a stored procedure. Our users are kicked off every time the transaction log is restored, though, which is the problem the above setup is supposed to resolve.










share|improve this question
























  • I'd guess it's due to the plan cache being cleared from the log restore. After your follow on run of the procedure, a new plan is generated and stored in cache and reused which is why you'd notice the performance improvement in subsequent runs. Check out this answer on ways to verify / check this.

    – scsimon
    May 13 at 16:18











  • Upon querying from sys.dm_exec_query_stats, the oldest plan cache doesn't seem to change, but the newest one (after sorting in desc by creation_time) is updated and appears to be copied over during Log Shipping, as they have the same time stamps after the transaction log restore has completed. It doesn't seem to have any effect on the slow first execution, though.

    – RIanGillis
    May 13 at 17:37

















7















We've set up log shipping to a secondary SQL server on Standby/ Read-Only to offload all SSRS report generation.

This works fine within the restrictions imposed by:



  1. Kicking out the user during the transaction log restore (we got around this by setting up multiple instances and restoring the most recent transaction logs using a round-robin schedule)

  2. The data being out of date by, at most, the time-frame indicated by the scheduled transaction log backup/ restore job.

Unfortunately, the first time any/ all stored procedure are run, after the transaction log was restored, it takes a much longer time to complete than normal. All subsequent executions of that same stored procedure complete within the expected time. If we then execute another stored procedure, the first time it is slow and all subsequent executions complete in the expected time.



For reference, the difference in execution is ~00:02 normally compared to ~01:00 on the first run.



I assume this has something to do with either the server execution statistics or the stored procedure parameter sniffing/ stored execution plan.

Is there any way to get around this issue? Or is this inherent to the transaction log restore?



If it was just the very first execution of any stored procedure we could get around this easily by executing any stored procedure upon restore, but it appears to affect the first time all stored procedures are executed.



I tried running count( * ) on the 11 tables the stored procedure I'm using for testing touches. The first run took 00:32, and subsequent count(*) took 00:00. Unfortunately, this did not have any impact on the first run of the stored procedure.



I don't see any results on either my primary or secondary servers for is_temporary stats, either before or after execution of a stored procedure.



I'm currently on SQL Server 2012


Query Exection Plan:
The query execution plan at first glance appears significantly different, however, upon saving the execution plan and opening the .sqlplan file generated they are exactly the same. The difference appears to be coming from the different versions of SSMS I am using, 2014 on the primary server and 2018 on the secondary. When viewing the execution plan on the secondary it shows underneath every node's % and time cost ### of ### (##%) - neither those numbers, nor the actual execution plan change upon further executions.
I also included client statistics and they show almost exactly the same, the only difference being the primary server executes with 1.4 seconds of Wait time on server replies and the secondary takes 81.3 seconds.

I do see a large number of PAGEIOLATCH_SH locks from the first execution, as you predicted:



diff after first exec vs diff after second exec
waiting_tasks_count 10903 918
wait_time_ms 411129 12768


One of the odd things about this situation, is, except for the round-robin multiple instances part of the setup we already have our production SSRS server reading from a standby/ read-only database that is fed by periodic transaction logs and do not experience these slow downs on the first execution of a stored procedure. Our users are kicked off every time the transaction log is restored, though, which is the problem the above setup is supposed to resolve.










share|improve this question
























  • I'd guess it's due to the plan cache being cleared from the log restore. After your follow on run of the procedure, a new plan is generated and stored in cache and reused which is why you'd notice the performance improvement in subsequent runs. Check out this answer on ways to verify / check this.

    – scsimon
    May 13 at 16:18











  • Upon querying from sys.dm_exec_query_stats, the oldest plan cache doesn't seem to change, but the newest one (after sorting in desc by creation_time) is updated and appears to be copied over during Log Shipping, as they have the same time stamps after the transaction log restore has completed. It doesn't seem to have any effect on the slow first execution, though.

    – RIanGillis
    May 13 at 17:37













7












7








7


2






We've set up log shipping to a secondary SQL server on Standby/ Read-Only to offload all SSRS report generation.

This works fine within the restrictions imposed by:



  1. Kicking out the user during the transaction log restore (we got around this by setting up multiple instances and restoring the most recent transaction logs using a round-robin schedule)

  2. The data being out of date by, at most, the time-frame indicated by the scheduled transaction log backup/ restore job.

Unfortunately, the first time any/ all stored procedure are run, after the transaction log was restored, it takes a much longer time to complete than normal. All subsequent executions of that same stored procedure complete within the expected time. If we then execute another stored procedure, the first time it is slow and all subsequent executions complete in the expected time.



For reference, the difference in execution is ~00:02 normally compared to ~01:00 on the first run.



I assume this has something to do with either the server execution statistics or the stored procedure parameter sniffing/ stored execution plan.

Is there any way to get around this issue? Or is this inherent to the transaction log restore?



If it was just the very first execution of any stored procedure we could get around this easily by executing any stored procedure upon restore, but it appears to affect the first time all stored procedures are executed.



I tried running count( * ) on the 11 tables the stored procedure I'm using for testing touches. The first run took 00:32, and subsequent count(*) took 00:00. Unfortunately, this did not have any impact on the first run of the stored procedure.



I don't see any results on either my primary or secondary servers for is_temporary stats, either before or after execution of a stored procedure.



I'm currently on SQL Server 2012


Query Exection Plan:
The query execution plan at first glance appears significantly different, however, upon saving the execution plan and opening the .sqlplan file generated they are exactly the same. The difference appears to be coming from the different versions of SSMS I am using, 2014 on the primary server and 2018 on the secondary. When viewing the execution plan on the secondary it shows underneath every node's % and time cost ### of ### (##%) - neither those numbers, nor the actual execution plan change upon further executions.
I also included client statistics and they show almost exactly the same, the only difference being the primary server executes with 1.4 seconds of Wait time on server replies and the secondary takes 81.3 seconds.

I do see a large number of PAGEIOLATCH_SH locks from the first execution, as you predicted:



diff after first exec vs diff after second exec
waiting_tasks_count 10903 918
wait_time_ms 411129 12768


One of the odd things about this situation, is, except for the round-robin multiple instances part of the setup we already have our production SSRS server reading from a standby/ read-only database that is fed by periodic transaction logs and do not experience these slow downs on the first execution of a stored procedure. Our users are kicked off every time the transaction log is restored, though, which is the problem the above setup is supposed to resolve.










share|improve this question
















We've set up log shipping to a secondary SQL server on Standby/ Read-Only to offload all SSRS report generation.

This works fine within the restrictions imposed by:



  1. Kicking out the user during the transaction log restore (we got around this by setting up multiple instances and restoring the most recent transaction logs using a round-robin schedule)

  2. The data being out of date by, at most, the time-frame indicated by the scheduled transaction log backup/ restore job.

Unfortunately, the first time any/ all stored procedure are run, after the transaction log was restored, it takes a much longer time to complete than normal. All subsequent executions of that same stored procedure complete within the expected time. If we then execute another stored procedure, the first time it is slow and all subsequent executions complete in the expected time.



For reference, the difference in execution is ~00:02 normally compared to ~01:00 on the first run.



I assume this has something to do with either the server execution statistics or the stored procedure parameter sniffing/ stored execution plan.

Is there any way to get around this issue? Or is this inherent to the transaction log restore?



If it was just the very first execution of any stored procedure we could get around this easily by executing any stored procedure upon restore, but it appears to affect the first time all stored procedures are executed.



I tried running count( * ) on the 11 tables the stored procedure I'm using for testing touches. The first run took 00:32, and subsequent count(*) took 00:00. Unfortunately, this did not have any impact on the first run of the stored procedure.



I don't see any results on either my primary or secondary servers for is_temporary stats, either before or after execution of a stored procedure.



I'm currently on SQL Server 2012


Query Exection Plan:
The query execution plan at first glance appears significantly different, however, upon saving the execution plan and opening the .sqlplan file generated they are exactly the same. The difference appears to be coming from the different versions of SSMS I am using, 2014 on the primary server and 2018 on the secondary. When viewing the execution plan on the secondary it shows underneath every node's % and time cost ### of ### (##%) - neither those numbers, nor the actual execution plan change upon further executions.
I also included client statistics and they show almost exactly the same, the only difference being the primary server executes with 1.4 seconds of Wait time on server replies and the secondary takes 81.3 seconds.

I do see a large number of PAGEIOLATCH_SH locks from the first execution, as you predicted:



diff after first exec vs diff after second exec
waiting_tasks_count 10903 918
wait_time_ms 411129 12768


One of the odd things about this situation, is, except for the round-robin multiple instances part of the setup we already have our production SSRS server reading from a standby/ read-only database that is fed by periodic transaction logs and do not experience these slow downs on the first execution of a stored procedure. Our users are kicked off every time the transaction log is restored, though, which is the problem the above setup is supposed to resolve.







sql-server sql-server-2012 stored-procedures restore log-shipping






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 13 at 21:01







RIanGillis

















asked May 13 at 15:41









RIanGillisRIanGillis

555




555












  • I'd guess it's due to the plan cache being cleared from the log restore. After your follow on run of the procedure, a new plan is generated and stored in cache and reused which is why you'd notice the performance improvement in subsequent runs. Check out this answer on ways to verify / check this.

    – scsimon
    May 13 at 16:18











  • Upon querying from sys.dm_exec_query_stats, the oldest plan cache doesn't seem to change, but the newest one (after sorting in desc by creation_time) is updated and appears to be copied over during Log Shipping, as they have the same time stamps after the transaction log restore has completed. It doesn't seem to have any effect on the slow first execution, though.

    – RIanGillis
    May 13 at 17:37

















  • I'd guess it's due to the plan cache being cleared from the log restore. After your follow on run of the procedure, a new plan is generated and stored in cache and reused which is why you'd notice the performance improvement in subsequent runs. Check out this answer on ways to verify / check this.

    – scsimon
    May 13 at 16:18











  • Upon querying from sys.dm_exec_query_stats, the oldest plan cache doesn't seem to change, but the newest one (after sorting in desc by creation_time) is updated and appears to be copied over during Log Shipping, as they have the same time stamps after the transaction log restore has completed. It doesn't seem to have any effect on the slow first execution, though.

    – RIanGillis
    May 13 at 17:37
















I'd guess it's due to the plan cache being cleared from the log restore. After your follow on run of the procedure, a new plan is generated and stored in cache and reused which is why you'd notice the performance improvement in subsequent runs. Check out this answer on ways to verify / check this.

– scsimon
May 13 at 16:18





I'd guess it's due to the plan cache being cleared from the log restore. After your follow on run of the procedure, a new plan is generated and stored in cache and reused which is why you'd notice the performance improvement in subsequent runs. Check out this answer on ways to verify / check this.

– scsimon
May 13 at 16:18













Upon querying from sys.dm_exec_query_stats, the oldest plan cache doesn't seem to change, but the newest one (after sorting in desc by creation_time) is updated and appears to be copied over during Log Shipping, as they have the same time stamps after the transaction log restore has completed. It doesn't seem to have any effect on the slow first execution, though.

– RIanGillis
May 13 at 17:37





Upon querying from sys.dm_exec_query_stats, the oldest plan cache doesn't seem to change, but the newest one (after sorting in desc by creation_time) is updated and appears to be copied over during Log Shipping, as they have the same time stamps after the transaction log restore has completed. It doesn't seem to have any effect on the slow first execution, though.

– RIanGillis
May 13 at 17:37










1 Answer
1






active

oldest

votes


















8














There are a few possible things going on here, here's a non-exhaustive list:



  • the execution plan cache is cleared by the log restore, so plans will need to be recompiled the first time. If your plans have long compile times, this could explain the difference. You didn't mention exactly how long the delay is on the first run compared to the subsequent runs

    • this one seems like the least likely - you can see your plan compilation time in actual execution plan XML


  • the buffer pool is also cleared during the restore, so all data has to be read from disk on the first execution

    • if this is the case, you'll likely see high PAGEIOLATCH* waits during the initial run if you check wait stats


Some things you could do to mitigate this are



  • "warm up" the buffer cache (by reading all data from important tables into memory using SELECT COUNT(*) FROM dbo.YourTable),

  • "warm up" the proc cache by running all the critical stored procedures as a post-restore step

Providing us with a "fast" and "slow" example of an execution plan could help us track down exactly which thing is happening.




If you are on SQL Server 2012 or newer, then it's possible that sync stats updates are causing the delay. These "readable secondary stats" get created in TempDB, since the log shipping secondary is read-only. You can read more about that here (the article is about AGs, but the same thing applies in this scenario):



AlwaysOn: Making latest statistics available on Readable Secondary, Read-Only database and Database Snapshot



If this is the problem causing your slowdown, then one solution would be to find those stats, and then create them in the production database, so that they are up-to-date and available after the restore. You can look for temp stats with this query:



SELECT * FROM sys.stats WHERE is_temporary = 1;



Based on the wait stats you provided, and the fact that the plans are the same, this is pretty conclusively due to the buffer pool being cleared by the log restore.



On a normal run, you get 12,768 ms (almost 13 seconds) of IO waits.

On the first run, you get 411,129 ms (almost 7 minutes) of IO waits.



The SELECT COUNT(*) approach you tried may not have helped due to different indexes being used by the actual procedure vs the COUNT(*) query. You have a few options here:



  1. Go through each execution plan and make note of the indexes being used, and then pull those indexes into memory as a post-restore step - using index hints this time (SELECT COUNT(*) FROM dbo.YourTable WITH (INDEX (IX_Index_Being_Used_By_Proc)))

  2. Go through the process of scripting out a process to run each procedure as a post-restore step (this seems a bit easier than option 1)

  3. Tune the queries so that they don't need to do so many reads (not sure how feasible this is)

  4. Speed up the I/O subsystem - get faster disks, local SSDs, more channels to the SAN, etc (this is probably the hardest and most expensive option





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%2f238034%2fafter-restoring-log-shipping-to-secondary-server-first-stored-procedure-executi%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









    8














    There are a few possible things going on here, here's a non-exhaustive list:



    • the execution plan cache is cleared by the log restore, so plans will need to be recompiled the first time. If your plans have long compile times, this could explain the difference. You didn't mention exactly how long the delay is on the first run compared to the subsequent runs

      • this one seems like the least likely - you can see your plan compilation time in actual execution plan XML


    • the buffer pool is also cleared during the restore, so all data has to be read from disk on the first execution

      • if this is the case, you'll likely see high PAGEIOLATCH* waits during the initial run if you check wait stats


    Some things you could do to mitigate this are



    • "warm up" the buffer cache (by reading all data from important tables into memory using SELECT COUNT(*) FROM dbo.YourTable),

    • "warm up" the proc cache by running all the critical stored procedures as a post-restore step

    Providing us with a "fast" and "slow" example of an execution plan could help us track down exactly which thing is happening.




    If you are on SQL Server 2012 or newer, then it's possible that sync stats updates are causing the delay. These "readable secondary stats" get created in TempDB, since the log shipping secondary is read-only. You can read more about that here (the article is about AGs, but the same thing applies in this scenario):



    AlwaysOn: Making latest statistics available on Readable Secondary, Read-Only database and Database Snapshot



    If this is the problem causing your slowdown, then one solution would be to find those stats, and then create them in the production database, so that they are up-to-date and available after the restore. You can look for temp stats with this query:



    SELECT * FROM sys.stats WHERE is_temporary = 1;



    Based on the wait stats you provided, and the fact that the plans are the same, this is pretty conclusively due to the buffer pool being cleared by the log restore.



    On a normal run, you get 12,768 ms (almost 13 seconds) of IO waits.

    On the first run, you get 411,129 ms (almost 7 minutes) of IO waits.



    The SELECT COUNT(*) approach you tried may not have helped due to different indexes being used by the actual procedure vs the COUNT(*) query. You have a few options here:



    1. Go through each execution plan and make note of the indexes being used, and then pull those indexes into memory as a post-restore step - using index hints this time (SELECT COUNT(*) FROM dbo.YourTable WITH (INDEX (IX_Index_Being_Used_By_Proc)))

    2. Go through the process of scripting out a process to run each procedure as a post-restore step (this seems a bit easier than option 1)

    3. Tune the queries so that they don't need to do so many reads (not sure how feasible this is)

    4. Speed up the I/O subsystem - get faster disks, local SSDs, more channels to the SAN, etc (this is probably the hardest and most expensive option





    share|improve this answer





























      8














      There are a few possible things going on here, here's a non-exhaustive list:



      • the execution plan cache is cleared by the log restore, so plans will need to be recompiled the first time. If your plans have long compile times, this could explain the difference. You didn't mention exactly how long the delay is on the first run compared to the subsequent runs

        • this one seems like the least likely - you can see your plan compilation time in actual execution plan XML


      • the buffer pool is also cleared during the restore, so all data has to be read from disk on the first execution

        • if this is the case, you'll likely see high PAGEIOLATCH* waits during the initial run if you check wait stats


      Some things you could do to mitigate this are



      • "warm up" the buffer cache (by reading all data from important tables into memory using SELECT COUNT(*) FROM dbo.YourTable),

      • "warm up" the proc cache by running all the critical stored procedures as a post-restore step

      Providing us with a "fast" and "slow" example of an execution plan could help us track down exactly which thing is happening.




      If you are on SQL Server 2012 or newer, then it's possible that sync stats updates are causing the delay. These "readable secondary stats" get created in TempDB, since the log shipping secondary is read-only. You can read more about that here (the article is about AGs, but the same thing applies in this scenario):



      AlwaysOn: Making latest statistics available on Readable Secondary, Read-Only database and Database Snapshot



      If this is the problem causing your slowdown, then one solution would be to find those stats, and then create them in the production database, so that they are up-to-date and available after the restore. You can look for temp stats with this query:



      SELECT * FROM sys.stats WHERE is_temporary = 1;



      Based on the wait stats you provided, and the fact that the plans are the same, this is pretty conclusively due to the buffer pool being cleared by the log restore.



      On a normal run, you get 12,768 ms (almost 13 seconds) of IO waits.

      On the first run, you get 411,129 ms (almost 7 minutes) of IO waits.



      The SELECT COUNT(*) approach you tried may not have helped due to different indexes being used by the actual procedure vs the COUNT(*) query. You have a few options here:



      1. Go through each execution plan and make note of the indexes being used, and then pull those indexes into memory as a post-restore step - using index hints this time (SELECT COUNT(*) FROM dbo.YourTable WITH (INDEX (IX_Index_Being_Used_By_Proc)))

      2. Go through the process of scripting out a process to run each procedure as a post-restore step (this seems a bit easier than option 1)

      3. Tune the queries so that they don't need to do so many reads (not sure how feasible this is)

      4. Speed up the I/O subsystem - get faster disks, local SSDs, more channels to the SAN, etc (this is probably the hardest and most expensive option





      share|improve this answer



























        8












        8








        8







        There are a few possible things going on here, here's a non-exhaustive list:



        • the execution plan cache is cleared by the log restore, so plans will need to be recompiled the first time. If your plans have long compile times, this could explain the difference. You didn't mention exactly how long the delay is on the first run compared to the subsequent runs

          • this one seems like the least likely - you can see your plan compilation time in actual execution plan XML


        • the buffer pool is also cleared during the restore, so all data has to be read from disk on the first execution

          • if this is the case, you'll likely see high PAGEIOLATCH* waits during the initial run if you check wait stats


        Some things you could do to mitigate this are



        • "warm up" the buffer cache (by reading all data from important tables into memory using SELECT COUNT(*) FROM dbo.YourTable),

        • "warm up" the proc cache by running all the critical stored procedures as a post-restore step

        Providing us with a "fast" and "slow" example of an execution plan could help us track down exactly which thing is happening.




        If you are on SQL Server 2012 or newer, then it's possible that sync stats updates are causing the delay. These "readable secondary stats" get created in TempDB, since the log shipping secondary is read-only. You can read more about that here (the article is about AGs, but the same thing applies in this scenario):



        AlwaysOn: Making latest statistics available on Readable Secondary, Read-Only database and Database Snapshot



        If this is the problem causing your slowdown, then one solution would be to find those stats, and then create them in the production database, so that they are up-to-date and available after the restore. You can look for temp stats with this query:



        SELECT * FROM sys.stats WHERE is_temporary = 1;



        Based on the wait stats you provided, and the fact that the plans are the same, this is pretty conclusively due to the buffer pool being cleared by the log restore.



        On a normal run, you get 12,768 ms (almost 13 seconds) of IO waits.

        On the first run, you get 411,129 ms (almost 7 minutes) of IO waits.



        The SELECT COUNT(*) approach you tried may not have helped due to different indexes being used by the actual procedure vs the COUNT(*) query. You have a few options here:



        1. Go through each execution plan and make note of the indexes being used, and then pull those indexes into memory as a post-restore step - using index hints this time (SELECT COUNT(*) FROM dbo.YourTable WITH (INDEX (IX_Index_Being_Used_By_Proc)))

        2. Go through the process of scripting out a process to run each procedure as a post-restore step (this seems a bit easier than option 1)

        3. Tune the queries so that they don't need to do so many reads (not sure how feasible this is)

        4. Speed up the I/O subsystem - get faster disks, local SSDs, more channels to the SAN, etc (this is probably the hardest and most expensive option





        share|improve this answer















        There are a few possible things going on here, here's a non-exhaustive list:



        • the execution plan cache is cleared by the log restore, so plans will need to be recompiled the first time. If your plans have long compile times, this could explain the difference. You didn't mention exactly how long the delay is on the first run compared to the subsequent runs

          • this one seems like the least likely - you can see your plan compilation time in actual execution plan XML


        • the buffer pool is also cleared during the restore, so all data has to be read from disk on the first execution

          • if this is the case, you'll likely see high PAGEIOLATCH* waits during the initial run if you check wait stats


        Some things you could do to mitigate this are



        • "warm up" the buffer cache (by reading all data from important tables into memory using SELECT COUNT(*) FROM dbo.YourTable),

        • "warm up" the proc cache by running all the critical stored procedures as a post-restore step

        Providing us with a "fast" and "slow" example of an execution plan could help us track down exactly which thing is happening.




        If you are on SQL Server 2012 or newer, then it's possible that sync stats updates are causing the delay. These "readable secondary stats" get created in TempDB, since the log shipping secondary is read-only. You can read more about that here (the article is about AGs, but the same thing applies in this scenario):



        AlwaysOn: Making latest statistics available on Readable Secondary, Read-Only database and Database Snapshot



        If this is the problem causing your slowdown, then one solution would be to find those stats, and then create them in the production database, so that they are up-to-date and available after the restore. You can look for temp stats with this query:



        SELECT * FROM sys.stats WHERE is_temporary = 1;



        Based on the wait stats you provided, and the fact that the plans are the same, this is pretty conclusively due to the buffer pool being cleared by the log restore.



        On a normal run, you get 12,768 ms (almost 13 seconds) of IO waits.

        On the first run, you get 411,129 ms (almost 7 minutes) of IO waits.



        The SELECT COUNT(*) approach you tried may not have helped due to different indexes being used by the actual procedure vs the COUNT(*) query. You have a few options here:



        1. Go through each execution plan and make note of the indexes being used, and then pull those indexes into memory as a post-restore step - using index hints this time (SELECT COUNT(*) FROM dbo.YourTable WITH (INDEX (IX_Index_Being_Used_By_Proc)))

        2. Go through the process of scripting out a process to run each procedure as a post-restore step (this seems a bit easier than option 1)

        3. Tune the queries so that they don't need to do so many reads (not sure how feasible this is)

        4. Speed up the I/O subsystem - get faster disks, local SSDs, more channels to the SAN, etc (this is probably the hardest and most expensive option






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited May 14 at 12:58









        Forrest

        2,8591824




        2,8591824










        answered May 13 at 16:26









        Josh DarnellJosh Darnell

        9,26632346




        9,26632346



























            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%2f238034%2fafter-restoring-log-shipping-to-secondary-server-first-stored-procedure-executi%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

            Wikipedia:Vital articles Мазмуну Biography - Өмүр баян Philosophy and psychology - Философия жана психология Religion - Дин Social sciences - Коомдук илимдер Language and literature - Тил жана адабият Science - Илим Technology - Технология Arts and recreation - Искусство жана эс алуу History and geography - Тарых жана география Навигация менюсу

            Bruxelas-Capital Índice Historia | Composición | Situación lingüística | Clima | Cidades irmandadas | Notas | Véxase tamén | Menú de navegacióneO uso das linguas en Bruxelas e a situación do neerlandés"Rexión de Bruxelas Capital"o orixinalSitio da rexiónPáxina de Bruselas no sitio da Oficina de Promoción Turística de Valonia e BruxelasMapa Interactivo da Rexión de Bruxelas-CapitaleeWorldCat332144929079854441105155190212ID28008674080552-90000 0001 0666 3698n94104302ID540940339365017018237

            What should I write in an apology letter, since I have decided not to join a company after accepting an offer letterShould I keep looking after accepting a job offer?What should I do when I've been verbally told I would get an offer letter, but still haven't gotten one after 4 weeks?Do I accept an offer from a company that I am not likely to join?New job hasn't confirmed starting date and I want to give current employer as much notice as possibleHow should I address my manager in my resignation letter?HR delayed background verification, now jobless as resignedNo email communication after accepting a formal written offer. How should I phrase the call?What should I do if after receiving a verbal offer letter I am informed that my written job offer is put on hold due to some internal issues?Should I inform the current employer that I am about to resign within 1-2 weeks since I have signed the offer letter and waiting for visa?What company will do, if I send their offer letter to another company