MariaDB ColumnStore: фильтрация подзапроса по вычисленному значению

0

У меня есть таблица, которая для определенного (time, country, asn) кортежа хранит несколько показателей:

+----------+---------+-------+-------+--------+--------+
|   time   | country |  asn  |  rtt  |  rexb  |  reqs  |
+----------+---------+-------+-------+--------+--------+
| 10000000 |   US    | 12345 |  40   |  0.05  |  5000  |
| 10000000 |   US    | 54321 |  120  |  0.15  |  500   |
| 10000000 |   MX    | 12345 |  300  |  0.25  |  1000  |
| 10000000 |   MX    | 54321 |  160  |  0.10  |  200   |
|   ....   |   ...   |  ...  |  ...  |  ....  |  ....  |

Во время общего использования я нормализую каждый из этих показателей до значения от 0 до 100, а затем возвращаю наибольшее значение, чтобы получить приблизительную оценку "насколько хорошо" соединение с этим ASN в этой стране:

SELECT
    country,
    asn,
    least(
        -- least(100, greatest(0, ...)) = clip value between 0 and 100
        least(100, greatest(0,
            -- normalize and protect against null values
            -- sample normalization:
            --     0 ms RTT = "100% good"
            --     300 ms RTT = "0% good"
            coalesce((300 - rtt) / 3, 0)
        )),
        least(100, greatest(0,
            -- sample normalization:
            --     0% REXB = "100% good"
            --     50% REXB = "0% good"
            coalesce((0.5 - rexb) / 0.5, 0)
        )),
        -- Other metrics may follow
    ) as quality
FROM
    metrics
WHERE
    time = 10000000 -- "current time"

Иногда я могу выполнять взвешенные средние значения, используя reqs (количество запросов в этой стране + ASN) для взвешивания:

SELECT
    country,
    least(
        least(100, greatest(0,
            coalesce((300 - sum(rtt*reqs)/sum(reqs)) / 3, 0)
        )),
        least(100, greatest(0,
            coalesce((0.5 - sum(rexb*reqs)/sum(reqs)) / 0.5, 0)
        ))
    ) as avg_quality
FROM
    metrics
WHERE
    time = 10000000 -- "current time"
GROUP BY
    country

Этот запрос работает отлично. Однако я столкнулся с проблемой, когда попытался использовать ее в подзапросе.

Моя цель состояла в том, чтобы определить, сколько стран имеет "среднее качество" ниже определенного порога:

SELECT 
    count(*)
FROM (
    SELECT
        country,
        least(
            least(100, greatest(0,
                coalesce((300 - sum(rtt*reqs)/sum(reqs)) / 3, 0)
            )),
            least(100, greatest(0,
                coalesce((0.5 - sum(rexb*reqs)/sum(reqs)) / 0.5, 0)
            ))
        ) as avg_quality
    FROM
        metrics
    WHERE
        time = 10000000 -- "current time"
    GROUP BY
        time, country
) t1
WHERE t1.avg_quality < 50

Это породило ошибку:

ERROR 1815 (HY000): Internal error: Lost connection to ExeMgr. Please contact your administrator

Я могу выполнить более простые подзапросы без проблем. Почему это не удается, и как я могу это исправить?

Я использую MariaDB, а таблица metrics использует механизм ColumnStore.

Быстрое обновление

Когда я заменяю WHERE t1.avg_quality < 50 с WHERE country = "US" запрос выполняется без проблем. Таким образом, он не имеет проблем с выполнением подзапроса или фильтрации. Это строго, когда я пытаюсь фильтровать на вычисленном столбце, что он терпит неудачу.

Теги:
mariadb
subquery
columnstore

1 ответ

0
Лучший ответ

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

SELECT 
    count(*)
FROM (
    SELECT
        country,
        least(
            least(100, greatest(0,
                coalesce((300 - sum(rtt*reqs)/sum(reqs)) / 3, 0)
            )),
            least(100, greatest(0,
                coalesce((0.5 - sum(rexb*reqs)/sum(reqs)) / 0.5, 0)
            ))
        ) as avg_quality
    FROM
        metrics
    WHERE
        time = 10000000 -- "current time"
    GROUP BY
        time, country
    HAVING
        avg_quality < 50
) t1

Ещё вопросы

Сообщество Overcoder
Наверх
Меню