对于具有高I / O操作的表,SQL Server查询效率低

时间:2018-03-16 13:43:23

标签: sql sql-server io query-performance sqlperformance

我正在尝试编写一个从列表中返回项目的sql脚本,如果该项目可以在列表中找到,如果没有,则返回添加到列表中的最新项目。我想出了一个使用count和if-else语句的解决方案。但是我的表有非常频繁的I / O操作,我认为这个解决方案效率很低。有没有人可以优化此解决方案或更好的方法。

这是我的解决方案:

DECLARE @result_set INT
SET @result_set = (
    SELECT COUNT(*) FROM
    ( SELECT *
        FROM notification p 
        WHERE p.code = @code 
            AND p.reference = @reference 
            AND p.response ='00'
    ) x
)

IF(@result_set > 0)
    BEGIN
        SELECT * 
        FROM notification p 
        WHERE p.code = @code 
            AND p.reference = @reference 
            AND p.response ='00'
    END
ELSE
    BEGIN
        SELECT
        TOP 1  p.*
        FROM notification p (nolock) 
        WHERE p.code = @code 
            AND p.reference = @reference
        ORDER BY p.id DESC
    END

我也认为应该有一种方法来重复这个选择语句:

SELECT *
    FROM notification p 
    WHERE p.code = @code 
        AND p.reference = @reference 
        AND p.response ='00'

我只是不够精通SQL以解决问题。

2 个答案:

答案 0 :(得分:4)

您可以这样做:

    //up boost-beast-client-async-ssl session code.   
    struct io_context_runner
    {
        boost::asio::io_context * ioc;
        void operator()()const
        {
            try{
                boost::asio::io_context::work w(*ioc);
                ioc->run();
            }catch(std::exception& e){
                fprintf(stderr, "e: %s\n", e.what());
            }
        }
    };

int main(int argc, char* argv[] ){

    try
    {
        int total_run = 1;
        if (argc > 1) total_run = atoi(argv[1]);

        const char* const host = "104.236.162.70" ;// IP of  isocpp.org
        const char* const port =  "443";  // 
        const char* const target= "/" ; //

        std::string const body = ""; //
        int version =  11;

        // The io_context is required for all I/O
        boost::asio::io_context ioc;

        // The SSL context is required, and holds certificates
        ssl::context ctx{ssl::context::sslv23_client};

        // This holds the root certificate used for verification
        load_root_certificates(ctx);

        typedef std::shared_ptr< async_http_ssl::session > pointer;

        for(int i = 0; i < total_run; ++i){
            pointer s = std::make_shared< async_http_ssl::session >(ioc  , ctx   ) ;
            usleep( 1000000 / total_run ) ;
            s->run( host, port, target, version ) ;
        }
        // Launch the asynchronous operation
        //std::make_shared<session>(ioc, ctx)->run(host, port, target, version);

        // Run the I/O service. The call will return when
        // the get operation is complete.
        std::thread t{ io_context_runner{ &ioc } } ;

        t.join();

        // If we get here then the connection is closed gracefully
    }
    catch(std::exception const& e)
    {
        std::cerr << "Error: " << e.what() << std::endl;
        return EXIT_FAILURE;
    }

       return EXIT_SUCCESS ;
}

这将首先返回响应为SELECT TOP (1) n.* FROM notification n WHERE p.code = @code AND p.reference = @reference ORDER BY (CASE WHEN p.response ='00' THEN 1 ELSE 2 END), id DESC; 的行,然后返回任何其他行。我希望'00'的另一列能够处理新近度,但您的示例代码并未提供任何可能的线索。

答案 1 :(得分:0)

WITH ItemIWant AS (
SELECT *
        FROM notification p 
        WHERE p.code = @code 
            AND p.reference = @reference 
            AND p.response ='00'
),
SELECT *
FROM ItemIWant
UNION ALL
SELECT TOP 1 *
FROM notification p 
WHERE p.code = @code 
    AND p.reference = @reference 
    AND NOT EXISTS (SELECT * FROM ItemIWant)
ORDER BY id desc

这将通过桌面上的最小传递来实现。如果ItemIWant没有返回任何行,它将只返回顶行。没有条件逻辑,因此可以有效地编译和索引。