1. SQL / Говнокод #14391

    −120

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    --==================================================
    -- используется для расчетного поля PPLS2BILLS_SRCO
    --==================================================
    CREATE FUNCTION RasSU 
                (   @Ves decimal(10,2),   
                    @Long decimal(10,2)   )
    RETURNS  decimal(10,2)
    AS
    BEGIN	
    DECLARE @SU decimal(10,2), @d decimal(10,2), @W decimal(10,2)
     
     SET @d=@Long / 100
     SET @W=ROUND((@Ves / 1000),2)
             IF  @d * SQRT(@W / 50) < 0 
                 BEGIN
                    SET @SU = 0
                END
             ELSE
                    SET @SU=@d * SQRT(@W / 50) 
    
    RETURN @SU
    END

    Looking for the dark matters.

    Запостил: bahamot, 20 Января 2014

    Комментарии (11) RSS

    • А вдруг вес отрицательный, а его корень мнимый? Тогда вообще сравнение будет неуместно.
      Ответить
    • сотые части копеек не волнуют.
      Ответить
    • имхо тут ГК вовсе не в алгоритме, а в использовании функции для этого. в Sql Server UDF работают в одном потоке, и не параллелятся. да и вообще их вызов это довольно дорогая операция. об этом можно почитать тут
      https://www.simple-talk.com/sql/t-sql-programming/clr-performance-testing/

      или наглядно посмотреть на этот скриншот https://www.simple-talk.com/iwritefor/articlefiles/1329-Results-SE-ConversionPercent3.jpg
      конечно это добавит определенный фарш в код, и скажется на дальнейшей поддержке, но производительности это определенно добавит.
      и да, мне досталась процедура, которая использовала скалярную функцию, которая делала ltrim(rtrim(lower(replace(replace(value, char(9),''),char(13),''))), после того, как я избавился от функции и написал этот код в процедуру, у меня запрос вместо 20-25 секунд работал 2-3.
      Ответить
      • > UDF
        А что тут вызывается из UDF?
        Ответить
      • > да и вообще их вызов это довольно дорогая операция
        > которая использовала скалярную функцию, которая делала ltrim(rtrim(lower(replace(replace(value, char(9),''),char(13),'')))
        Посмотрел таблички... Грустно стало... Ну неужели хреновина, которая стоит столько бабок, не может сделать простейшие оптимизации в духе инлайна? Какого хрена это должен делать программист? Код в хранимках и без того не айс, так еще и этот рукопашный инлайн для полного счастья...

        Или во всех СУБД такая ерунда с тормозами при использовании UDF?
        Ответить
        • Потестим на бесплатном слонёнке:
          create or replace function cleanup_string(value varchar(255)) returns varchar(255) as $$
          begin
              return ltrim(rtrim(lower(replace(replace(value, chr(9),''),chr(13),''))));
          end;
          $$ language plpgsql immutable;
          
          create or replace function test_udf(s varchar(255)) returns varchar(255) as $$
          begin
              for i in 1..1000000 loop
                  s = cleanup_string(s);
              end loop;
              return s;
          end;
          $$ language plpgsql;
          
          create or replace function test_inline(s varchar(255)) returns varchar(255) as $$
          begin
              for i in 1..1000000 loop
                  s = ltrim(rtrim(lower(replace(replace(s, chr(9),''),chr(13),''))));
              end loop;
              return s;
          end;
          $$ language plpgsql;
          
          select test_inline('  ddhaskhdkj d as  das da sd sad  ');
          Time: 1445,970 ms
          
          select test_udf('  ddhaskhdkj d as  das da sd sad  ');
          Time: 2390,873 ms
          Рукопашный инлайн дал на 40% меньшее время исполнения. Имхо, 40% не такая уж заоблачная цифра, чтобы ради нее превращать все функции в помойку... Разве что редкие, особо горячие.

          P.S. Сорри за длиннопост.
          Ответить
      • P.S. Имхо, такой микрооптимизацией нужно заниматься уже тогда, когда заметили, что функция тормозит и реально мешает работе. Т.е. если эти 25 секунд нужно подождать грубо говоря раз в месяц или квартал - не стоит переделывать наглядный код в копипастный фарш...
        Ответить
        • обычно одну функцию вылизывают до наносекунд, а рядом лежит монстр, который на минуту зависает, но его никто не трогает - ибо страшно
          Ответить
          • > ибо страшно
            Потому что он тоже был вылизан до блеска наносекунд, вместо высокоуровневой оптимизации, угу.
            Ответить
          • Ищем не там, где потеряли, а там, где светло?
            Ответить

    Добавить комментарий