выполнение кросс-соединения - PullRequest
2 голосов
/ 23 марта 2011

Я создаю веб-страницу с фотографиями. Для того, чтобы сделать все комбинации контента, я использую кросс-соединение. Допустим, у меня есть следующая простая таблица:

настольные фотографии

id filename
------------
1   a.jpg
2   b.jpg
3   c.jpg
4   d.jpg
5   e.jpg

Количество комбинаций, которые я могу составить из таблицы, равно 10, и это

1,2
1,3
1,4
1,5
2,3
2,4
2,5
3,4
3,5
4,5

Я получаю вышеуказанный результат, используя следующий перекрестный запрос

    SELECT cp1.id,
           cp2.id 
      from photos as cp1 
cross join photos as cp2 
     where cp1.id < cp2.id

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

    SELECT cp1.id,
           cp1.filename,
           cp2.id, 
           cp2.filename 
      from challenge_photos as cp1 
cross join challenge_photos as cp2 
     where cp1.id < cp2.id 
       and (cp1.id,cp2.id) not in ( (x1,x2), (x1,x2) ) 
       and cp1.id = something 
       and cp2.img_id != something

Пока что эти запросы работают просто отлично. Каждый запрос занимает около 0,0002 секунды (из 2300 строк) у phpmyadmin.

Давайте предположим, что в моей таблице 2000 строк. Количество возможных комбинаций огромно. У меня будут проблемы, когда на моем веб-сайте будет много активных пользователей?

Ответы [ 2 ]

3 голосов
/ 23 марта 2011

Я бы предложил создать тестовую базу данных различных размеров и протестировать запрос, чтобы увидеть его производительность. Делая аналогичный запрос для таблицы из 29 тыс. Строк, я получал запросы по 10-30 мс и аналогичные числа в таблице из 70 тыс. Строк, что может показаться, что запрос не совсем ужасен. Похоже, что запросы также кэшируются, что означает значительную выгоду, если ваша таблица видит мало записей и много одинаковых запросов.

Существует также значительная асимметрия в вашем примере запроса: если cp1.id мал, вы получаете 100/1000 строк, а если он большой, вы получаете только несколько.

Этот вопрос SO относится к запросу перекрестного соединения с предложением WHERE, действующим как внутреннее соединение.

0 голосов
/ 23 марта 2011

С 2000, может и нет. С 200 тысячами фотографий, вероятно, да.

Альтернативным способом было бы:

  1. создать таблицу испытаний с (cp1, cp2).
  2. сделать триггер, чтобы при вставке новой фотографии новые вызовы добавлялись в предыдущую таблицу в соответствии с вашими правилами
  3. тогда ваш запрос будет (ВНУТРЕННИМ) присоединиться к Challenge и (вдвое больше) таблицам ChallengePhoto.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...