Как повысить скорость этого запроса на обновление SQL? - PullRequest
1 голос
/ 24 марта 2012

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

Я использую SQL Compact 3.5 в качестве локальной базы данных. Программа написана на VB.NET.

Проблема в том, что запрос одного из моих таблиц занимает слишком много времени.

Стол игрока имеет, помимо прочего, id, skill, school, weight, starter.

  • id идентификатор игрока
  • skill это уровень мастерства игрока
  • school - это внешний ключ, указывающий на идентификатор школьного стола
  • weight - это один из 14 разных номеров

Я пытаюсь установить значение starter = 'true' для игрока с наивысшим навыком при заданном весе для данной школы. Так что если в школе 100 игроков, то будет 14 стартеров, по одному на каждый вес.

В таблице игроков насчитывается 170 000 игроков, каждый из которых имеет 1 из 14 различных весов, и каждый из них принадлежит 1 из 4500 школ.

Кто-то прокомментировал ниже и показал это утверждение, которое, кажется, находится на правильном пути. Я новичок и пока не реализовал его.

  "UPDATE p " &
  "SET starter = 'TRUE' " &
  "FROM player p" &
  "JOIN (" &
  "SELECT DISTINCT school, weight, MAX(skill) AS MaxSkill " &
  "FROM player " &
  "GROUP BY school, weight" &
  ") q ON q.school = p.school AND q.weight = p.weight AND q.MaxSkill =
   p.skill"

Ответы [ 2 ]

3 голосов
/ 24 марта 2012

Вместо того, чтобы подходить по группам, строка за строкой, этот запрос на обновление выполняет все сразу:

Во-первых, он собирает самые высокие значения skill для каждой комбинации school / weight.

Затем он соединяет это с player, имеющим соответствующую комбинацию school / weight / skill, и затем устанавливает это player на стартер.

UPDATE p
SET starter = 'TRUE'
FROM player p 
JOIN (
    SELECT school, weight, MAX(skill) AS MaxSkill
    FROM player
    GROUP BY school, weight
) maxResults 
    ON maxResults.school = p.school 
    AND maxResults.weight = p.weight 
    AND maxResults.MaxSkill = p.skill

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

1 голос
/ 24 марта 2012

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

В любом случае, вот запрос, который должен работать для всех РСУБД

UPDATE player a SET starter = TRUE
WHERE NOT EXISTS (SELECT '1'
                  FROM player b
                  WHERE b.school = a.school
                  AND b.weight = a.weight
                  AND b.skill > a.skill)

Внутренний запрос должен возвращать null (таким образом, устанавливая starter true), если:

  1. В школе нет других игроков
  2. В этой же школе нет игроков,в той же весовой категории
  3. Нет игроков с более высоким уровнем квалификации для той же школы и весового класса
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...