На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! информация о разделе
user posted imageДанный раздел предназначается для обсуждения вопросов использования баз данных, за исключением составления запросов на SQL. Для этого выделен специальный раздел. Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ.

Модераторы: Chow, Bas, MIF
Страницы: (2) 1 [2]  все  ( Перейти к последнему сообщению )  
> Как сравнить два запроса в плане эффективности
    Цитата Akina @
    Я вообще считаю, что следует начать с нормализации.

    С нормализацией все в поряде - все таблицы (кроме одной) вяжутся по простому ключу. И только одна - по составному. Но я посчитал, мне будет так "дешевле" обрабатывать. А в этом случае целостность обеспечивается бизнес-логикой приложения. Я говорю о таблице родственных отношений. Если спецом не лезть руками в БД, клиентское приложение при модификации всегда оставляет только одну связь, а она расшифровывается таблицей учитывая пол клиентов и номер отношения.

    Вообщем начало скрипта вымучал, все групповые вычисления вынес таки из полей, обошелся двумя джоинами и группировкой.
    Получил ускорение примерно в 7 раз. Получилось вот так:

    ExpandedWrap disabled
      SELECT
        x."Id",
        x."Age",
        x."Sex",
        CASE WHEN
          SUM(CASE WHEN COALESCE(x."Childs1",0)>0 THEN 1 ELSE 0 END) = 0 AND
          SUM(CASE WHEN COALESCE(fa2."Relation",0)>0 THEN 1 ELSE 0 END) = 0 AND
          x."Age" < 18
          THEN 1 ELSE 0 END AS "IsChild",
        CASE WHEN
          SUM(CASE WHEN COALESCE(x."Childs1",0)>0 THEN 1 ELSE 0 END) > 0 AND
          SUM(CASE WHEN COALESCE(fa2."Relation",0)>0 THEN 1 ELSE 0 END) = 0
          THEN 1 ELSE 0 END AS "IsParent"
      FROM (
        SELECT
          c."Id",
          CASE WHEN c."YearOfBirth" < 150 THEN c."YearOfBirth" ELSE (EXTRACT(year FROM now()) - c."YearOfBirth") END AS "Age",
          c."Gender" AS "Sex",
          c."Gender",
          CASE WHEN ((COALESCE(fa1."Relation",0)>0) AND (fa1."ClientOne" = c."Id")) THEN fa1."ClientTwo"
               WHEN ((COALESCE(fa1."Relation",0)>0) AND (fa1."ClientTwo" = c."Id")) THEN fa1."ClientOne" ELSE 0 END AS "Childs1"
        FROM
          "Clients" AS c
        LEFT JOIN
          "Family" AS fa1 ON
            (fa1."ClientOne" = c."Id" AND fa1."Relation" IN (15,16,19,20)) OR
            (fa1."ClientTwo" = c."Id" AND fa1."Relation" IN (10,21,22,30))
        WHERE
          c."FamilyId" IN (
            SELECT
              c."FamilyId"
            FROM
              "Service" AS s,
              "Service2Clients" AS sc,
              "Clients" AS c
            WHERE
              c."Id" = sc."Client" AND
              sc."Service" = s."Id" AND
              s."Date" BETWEEN '2015-01-01' AND '2015-12-31' AND
              s."State" > 0 AND
              sc."Present"
          )
      ) AS x
      LEFT JOIN
        "Family" AS fa2 ON
          (fa2."ClientOne" = x."Childs1" AND fa2."Relation" IN (15,16,19,20)) OR
          (fa2."ClientTwo" = x."Childs1" AND fa2."Relation" IN (10,21,22,30))
      GROUP BY
        x."Id", x."Age", x."Sex"


    Только вот не уверен с это конструкцией, не слишком ли параноидальная перестраховка?
    ExpandedWrap disabled
      SUM(CASE WHEN COALESCE(x."Childs1",0)>0 THEN 1 ELSE 0 END) = 0

    Может хватило бы так?
    ExpandedWrap disabled
      SUM(x."Childs1") = 0
    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
    0 пользователей:


    Рейтинг@Mail.ru
    [ Script execution time: 0,0256 ]   [ 15 queries used ]   [ Generated: 19.04.24, 18:45 GMT ]