MySQL:任何改进最佳匹配存储过程的建议

发布于 2024-11-19 07:06:32 字数 582 浏览 3 评论 0原文

对于我正在从事的项目,我必须扫描密钥以获得最佳匹配。只有这些扫描才会对我们的测试系统造成大量负载。有人知道我该如何改进吗?我们已经尝试过临时表和游标。

我们正在使用的代码示例:

SET keyLength = (LENGTH(key)-1);
WHILE keyLength >=1 DO
    SELECT COUNT(*) INTO resultCount FROM keytable
    WHERE I ScreeningKey = (SELECT SUBSTRING(key)-,1,keyLength));
    IF (0 < resultCount) THEN
        SELECT ScreeningKey INTO bestMatchScreeningKey FROM keytable 
        WHERE AND ScreeningKey = (SELECT SUBSTRING(key)-,1,keyLength));

        /*go to step4*/
        LEAVE Step4;
    END IF;
    SET keyLength = keyLength-1;
END WHILE;

For a project I am working on I have to scan a key for best match. Only these scan are causing a lot of load on our test system. Any body an idea how I can improve this? We already tried temporary tables and Cursors.

An example of the code we are using:

SET keyLength = (LENGTH(key)-1);
WHILE keyLength >=1 DO
    SELECT COUNT(*) INTO resultCount FROM keytable
    WHERE I ScreeningKey = (SELECT SUBSTRING(key)-,1,keyLength));
    IF (0 < resultCount) THEN
        SELECT ScreeningKey INTO bestMatchScreeningKey FROM keytable 
        WHERE AND ScreeningKey = (SELECT SUBSTRING(key)-,1,keyLength));

        /*go to step4*/
        LEAVE Step4;
    END IF;
    SET keyLength = keyLength-1;
END WHILE;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

星星的轨迹 2024-11-26 07:06:32

不使用 SELECT COUNT(*),只需使用 IF EXISTSIF EXISTS 可以在找到匹配项后立即停止扫描,而 COUNT(*) 则需要遍历整个表来统计计数。

所以,你最终会得到类似的结果:(我不太使用 MySQL,所以我不确定语法,我复制粘贴了你的语法,这对我来说看起来不太正确......)

SET keyLength = (LENGTH(key)-1);
WHILE keyLength >=1 DO
    IF EXISTS (SELECT * FROM keytable
               WHERE I ScreeningKey = (SELECT SUBSTRING(key)-,1,keyLength))) THEN
        SELECT SUBSTRING(key)-,1,keyLength INTO bestMatchScreeningKey;

        /*go to step4*/
        LEAVE Step4;
    END IF;
    SET keyLength = keyLength-1;
END WHILE;

Instead of using SELECT COUNT(*) just use IF EXISTS. The IF EXISTS can stop scanning as soon as it finds a match, while COUNT(*) needs to go through the entire table to tally up that count.

So, you would end up with something like: (I don't use much MySQL, so I'm not sure on the syntax and I copy-pasted your syntax which doesn't look quite right to me...)

SET keyLength = (LENGTH(key)-1);
WHILE keyLength >=1 DO
    IF EXISTS (SELECT * FROM keytable
               WHERE I ScreeningKey = (SELECT SUBSTRING(key)-,1,keyLength))) THEN
        SELECT SUBSTRING(key)-,1,keyLength INTO bestMatchScreeningKey;

        /*go to step4*/
        LEAVE Step4;
    END IF;
    SET keyLength = keyLength-1;
END WHILE;
南风起 2024-11-26 07:06:32

像这样的事情怎么样?

对于未找到数据的每次迭代,它都会跳转到异常块(跳过 LEAVE),直到找到记录。

这将节省您为每次迭代进行 2 次选择的时间。

注意我添加了 LIMIT 1 来阻止 select 返回多行的可能性。

SET keyLength = (LENGTH(key)-1);
WHILE keyLength >=1 DO
BEGIN
    SELECT SUBSTRING(key)-,1,keyLength INTO bestMatchScreeningKey LIMIT 1;
    LEAVE Step4;
EXCEPTION
    WHEN no_data_found THEN
        NULL;
    WHEN others THEN
        RAISE;
END;
    SET keyLength = keyLength-1;
END WHILE;

How about something like this ?

For every iteration where no data is found it jumps into the exception block (skipping the LEAVE) until a record is found.

This will save you doing 2 selects for each iteration.

Note I added a LIMIT 1 to stop the possibility of the select returning several rows.

SET keyLength = (LENGTH(key)-1);
WHILE keyLength >=1 DO
BEGIN
    SELECT SUBSTRING(key)-,1,keyLength INTO bestMatchScreeningKey LIMIT 1;
    LEAVE Step4;
EXCEPTION
    WHEN no_data_found THEN
        NULL;
    WHEN others THEN
        RAISE;
END;
    SET keyLength = keyLength-1;
END WHILE;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文