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

    −860

    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
    23. 23
    24. 24
    25. 25
    26. 26
    SELECT
        node.nid AS nid,
        location.latitude AS location_latitude,
        location.longitude AS location_longitude,
        node.title AS node_title,
        node.language AS node_language,
        location.lid AS location_lid,
        (IFNULL(ACOS(0.501284223863*COS(RADIANS(location.latitude))*(0.863228195442*COS(RADIANS(location.longitude)) + 0.504813908876*SIN(RADIANS(location.longitude))) + 0.865282686124*SIN(RADIANS(location.latitude))), 0.00000)*6362105.74365) AS location_distance,
        node_data_field_rate_prior.field_rate_prior_amount AS node_data_field_rate_prior_field_rate_prior_amount,
        node_data_field_rate_prior.field_rate_prior_currency AS node_data_field_rate_prior_field_rate_prior_currency,
        node.type AS node_type, node.vid AS node_vid,
        node_data_field_rate_prior.field_rate_reg_amount AS node_data_field_rate_prior_field_rate_reg_amount,
        node_data_field_rate_prior.field_rate_reg_currency AS node_data_field_rate_prior_field_rate_reg_currency,
        node_data_field_rate_prior.field_rate_vip_amount AS node_data_field_rate_prior_field_rate_vip_amount,
        node_data_field_rate_prior.field_rate_vip_currency AS node_data_field_rate_prior_field_rate_vip_currency
      FROM node node
      LEFT JOIN location_instance location_instance ON node.vid = location_instance.vid
      LEFT JOIN location location ON location_instance.lid = location.lid
      LEFT JOIN content_type_dta_kiosk node_data_field_rate_prior ON node.vid = node_data_field_rate_prior.vid
      WHERE node.type in ('dta_kiosk')
        AND (location.latitude > 40.9991009563 
          AND location.latitude < 59.0008990437 
          AND location.longitude > 5.91311892539 
          AND location.longitude < 34.0868810746
        )
      ORDER BY location_distance ASC

    Запостил: vectoroc, 14 Января 2011

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

    • Ого, киоски в округе ищут?
      Ответить
    • такими запросами и не одну базу, и не один сервак на колени поставить можно.
      Ответить
      • на колени, смерд! прощайся с жизнью, сучий сын! (ц) ))))))
        Ответить
      • Да лан, индекс по latitude-longitude и заебок. Сам такое пейсал. chotut.com кстати ;)
        Ответить
        • там сортировочка по вычисляемому полю, если вы не заметили.

          > ORDER BY location_distance ASC

          в общем, это не базы работа такой херней страдать. на любом языке программирования это будет намного эффективней реализовать.

          если в результате много строк и/или выполняется много таких запросов паралельно, т.к. результаты запроса должны быть полностью в памяти кэшированы (что бы отсортировать) то: либо у базы все кэши будут засорены этим мусором, либо сортировка будет идти через диск.

          да, современные базы такое тянут. вопрос только "зачем?"
          Ответить
          • >> там сортировочка по вычисляемому полю, если вы не заметили.
            Да, действительно, не заметил.

            >>в общем, это не базы работа такой херней страдать
            А вот тут спорно, От объема выборки зависит. Собссно сортируя это в скрипте все равно ту же память съешь. А учитывая криворукость разработчика - наверняка еще и потеряешь и в производительности и в ресурсах.

            Кстати в Firebird'е например есть специальный механизм для индексирования вычисляемых полей, ключевое слово COMPUTED BY.
            Ответить
            • > Собссно сортируя это в скрипте все равно ту же память съешь.

              в скрипте эта память все равно должна быть выделена - для хранения результата запроса.

              для баз идеально когда они могут данные (почти) на прямую с диска клиенту фигачить. что и есть одно из назначений индексов: маппинг строк таблицы в блоки на диске. в идеале, запрос конвертится в fsm которая просто ходит по индексам и гонит данные с той скоростью с которой их может клиент вычитывать.

              > Кстати в Firebird'е например есть специальный механизм для индексирования вычисляемых полей, ключевое слово COMPUTED BY.

              да они почти везде есть (function-based index в Оракакле). проблема в том что ты тогда теряешь время на каждом insert/update.
              Ответить
              • >> в скрипте эта память все равно должна быть выделена - для хранения результата запроса.
                ваще да, тут согласен :)

                >>для баз идеально
                ну это всем известно, но случай-то совсем не идеальный

                >> проблема в том что ты тогда теряешь время на каждом insert/update
                Естественно. Нужен сбалансированный подход к индексам, впрочем это тоже азбука

                Все таки на не раскрыта тема, почему надо делать эту сортировку самому а не перевалить на плечи БД. ИМХО в лучшем случае, написав идеальный код, получишь немного лучший результат, но потратишь массу времени.

                В конце концов лучше сделать сначала так, никто не мешает в случае эпичных тормозов уже задуматься над переносом этой логики в серверный скрипт.
                Ответить
                • > Все таки на не раскрыта тема, почему надо делать эту сортировку самому а не перевалить на плечи БД.

                  блин. мануал по тюнингу SQL для твоей любимой RDBMS в руки и читать.

                  я проходил Оракакловский перформанс тренинг, и такие фишки там упомянались. концепция большинства оптимизаций: чем меньше базе нужно делать, тем лучше; чем лучше то что ты делаешь мапится на нативную функциональность, тем лучше; и т.д. и т.п.

                  в частности сортировки которые не мапятся на индекс, требуют доп памяти для того что бы данные отсортировать. в худшем случае, только для сортировки, данные могут быть записаны временно на диск, и потом мерж сортом клиенту с диска отдаватся.

                  > ИМХО в лучшем случае, написав идеальный код, получишь немного лучший результат, но потратишь массу времени.

                  как в пыхе это делается, не помню. но на перле это почти тривиально, типа `sort { cmp_code } @{$sth->fetchall_arrayref};`
                  Ответить
                  • перекладывание работы с БД на пхп - фиговая оптимизация.
                    computed by index тут не применим (mysql вроде нет такого?)

                    если предварительно отфильтровать точки по координатам, получается не такие уж и большие выборки, сортировка которых происходит быстро
                    Ответить
                    • В целом согласен, НО:

                      >> mysql вроде нет такого?
                      А где написано что это MySQL ?

                      >>если предварительно отфильтровать точки по координатам, получается не такие уж и большие выборки, сортировка которых происходит быстро
                      На самом деле мы не знаем сколько там точек. Может их более 9000 в этих координатах
                      Ответить
                    • Если масштабировать приложение, то проще будет добавить сервак с PHP, чем слэйвы для БД. Но это, если планируется расширение.
                      Ответить
                  • >>я проходил Оракакловский перформанс тренинг, и такие фишки там упомянались. концепция большинства оптимизаций: чем меньше базе нужно делать, тем лучше

                    Ну это ожидаемо. Естественно, чтобы меньше вопросов к Ораклу возникало, его преподы и учат меньше его грузить. Чтобы потом народ не вопил что Ора-кал !
                    Ответить
                  • >>а перле это почти тривиально, типа `sort { cmp_code }

                    Может я тупой, но почему вы думаете что MySQL не делает примерно то же самое? А если так, то нафига городить велосипед?
                    Ответить
                    • > Может я тупой, но почему вы думаете что MySQL не делает примерно то же самое?

                      направление мысли правильное - MySQL делает то же самое. но: devil is in the details.

                      сортировка требует доп памяти.

                      память CGI приложения как правило ресайклится почти сразу. и ее много. почти ни один фреймворк (по умолчанию) не ставит никаких жестких ограничений на расход памяти. (наверное Жаба с ее граблями выделения памяти единственное известное мне исключение где глобальный лимит всегда есть.)

                      память SQL сервака как правило имеет жесткий лимит и используется для многих вещей. самая главная часть: это кэш часто используемых таблиц. память которая будет расходоватся для сортировки скорее всего должна будет отобрана у кэша, что значит что какая-то таблица будет выкинута из памяти. что значит что эта таблицу нужно будет перечитать с диска.

                      суммируя: с точки зрения производительности память SQL сервака дороже чем память CGI скрипта. один скрипт обламается - это мелкая проблема. один сервак будет постоянно на диск ходит - все скрипты в жопе.

                      совсем суммируя: сортировка в SQL которая не мапится на индекс есть говно.
                      Ответить
                      • Честно говоря не знаю подробностей работы менеджеров памяти у SQL-серваков, поэтому возможно тут вы и правы.

                        >>совсем суммируя: сортировка в SQL которая не мапится на индекс есть говно.

                        Опять же не всегда. Может этот запрос для административных целей или для построения отчета раз в день. Лучше один раз напрячь сервак неиндексированной сортировкой чем натянуть лишний индекс и напрягать сервак каждой вставкой. Согласны?
                        Ответить
                        • да. само собой разумеется.
                          Ответить
                          • помню, как выли холодильники сервера, когда манагеры обнаружили, что ежедневный отчет можно получать в реальном времени...
                            Ответить
    • ойбля. родной друпал
      node.nid AS nid,
      ..FROM node node
        LEFT JOIN location_instance location_instance ON node.vid = location_instance.vid

      даже по ревизиям ноды есть.
      а чо за модуль?
      а то сдается мне что это говно нагенерено чем то типа views - особо глядя на вот это
      AND (location.latitude > 40.9991009563 
            AND location.latitude < 59.0008990437 
            AND location.longitude > 5.91311892539 
            AND location.longitude < 34.0868810746
          )



      PS. одминам. сделайтежекнопкидляббкода.неудобноблять!
      PPS. ниделя друпала на гавнакоде
      Ответить
      • views+cck+location в основном
        Ответить
        • бля я знал я знал. этопиздец :)
          имеенно потому запросы с более сложными условиями я пишу сам, а потом натравливаю на них db_rewrite_sql и втыкаю в тему(там где можно было бы вьюху к ноде привязать)
          ибо писец.
          вы на д7 чтото уже апгрейдили? не умирают данные? :)
          Ответить
          • d7 еще не трогал. а должны умирать?
            Ответить
            • да вот хуй ево знает. смотрел - вроде скрипты апдейта аттачи переделывают в файлфилды и все поля и прочее переводят в ядреные поля, но ссыкотно как-то мне :)
              судя по всему данные то никуда не денутся а код заново писать.
              Ответить
    • тащемта, конкретно такое дело гораздо шустрее выполняется какойнить из OpenGIS-овских надстроек - под мускуль точно есть. Там и пространственные индексы, и быстрые выборки по попаданию в область, и нативные (не на sql-е) функции расстояния и прочая.
      Ответить

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