2010-09-16 8 views
6

В настоящее время я создал Facebook-подобную страницу, которая извлекает уведомления из разных таблиц, скажем, около 8 таблиц. Каждая таблица имеет разную структуру с разными столбцами, поэтому первое, что приходит в голову, это то, что у меня будет глобальная таблица, например, оглавление, и обновляйте ее с каждым новым ударом. Я знаю, что вставки ресурсоемкие, но я надеялся, что, поскольку это статическая таблица, я бы добавил только одну новую запись каждые 100 посетителей, поэтому я подумал: «МОГУТ», я мог бы с этим справиться, но я ошибся. Мне удалось получить тупики от трех человек, забивающих сайт.MySql Temp Tables VS Views VS php arrays

Так или иначе, теперь мне нужно повторить его, используя другой метод. Сначала я собирался делать представления, но у меня проблема с мнениями. Выбранная таблица должна содержать идентификатор пользователя. Ниже приведен пример выбора из php:

$get_events = " 

    SELECT id, " . $userId . ", 'admin_events', 0, event_start_time 
     FROM admin_events 
     WHERE CURDATE() < event_start_time AND 
       NOT EXISTS(SELECT id 
         FROM admin_event_registrations 
         WHERE user_id = " . $userId . " AND admin_events.id = event_id) AND 
       NOT EXISTS(SELECT id 
         FROM admin_event_declines 
         WHERE user_id = " . $userId . " AND admin_events.id = event_id) AND 
       event_capacity > (SELECT COUNT(*) FROM admin_event_registrations WHERE event_id = admin_events.id) 
      LIMIT 1 

Извините за беспорядок. В любом случае, как вы можете видеть, мне нужно вернуть идентификатор пользователя со страницы в качестве выбранного столбца из таблицы. Я не мог понять, как это сделать с представлениями, поэтому я не думаю, что взгляды - это то, как я буду руководить, потому что есть намного больше таких типов запросов. Я пришел из фона MSSQL, и мне нравятся хранимые процедуры, поэтому, если есть хранимые процедуры для MYSQL, это будет отлично.

Далее я начал думать о временных таблицах. Таблица будет в памяти, таблица будет, вероятно, 150 строк макс, и не будет взаимоблокировок. До сих пор очень дорого делать вставки на временной таблице? Я в конечном итоге сбой сервера? Сейчас у нас есть, возможно, 100 пользователей в день, но я хочу попытаться быть будущим доказательством, когда мы получим больше пользователей.

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

$my_array[0]["date_created"] = <current_date> 

Проблема с выше является то, что я должен сортировать date_created, но это многомерные массив.

В любом случае, чтобы вытащить 150-200 записей MAX из базы данных, какой подход вы бы взяли? Temp Table, View или php?

ответ

5

Некоторые мысли:

Temp Таблицы: временные таблицы будут только продолжаться до тех пор, пока сессия жива. Если вы запустите код в скрипте PHP, временная таблица будет автоматически уничтожена, когда скрипт завершит выполнение.

Просмотры: Это в основном для скрытия сложности в том, что вы создаете его с помощью соединения, а затем получаете к нему доступ как отдельную таблицу. Подчеркнутый код - инструкция SELECT.

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

хранимые процедуры: Там хранятся процедуры в MySQL - см: http://dev.mysql.com/doc/refman/5.0/en/stored-routines-syntax.html

Моя рекомендация: Во-первых, переписать запрос с использованием MySQL Query Analyzer: http://www.mysql.com/products/enterprise/query.html

Теперь я будет использовать PDO, чтобы поместить мои значения в массив с помощью PHP. Это все равно оставит начальный тяжелый подъем в DB Engine и не позволит вам совершать несколько вызовов на сервере БД.

+0

В представлениях «select' нет необходимости». Они также могут быть временными таблицами. См. Http://www.percona.com/blog/2007/08/12/mysql-view-as-performance-troublemaker/ и http://www.percona.com/blog/2010/05/19/a -workaround-for-the-performance-problems-of-temptable-views /, и http://dba.stackexchange.com/a/16376/9405 – Pacerier

0

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

Переключение типа таблицы в InnoDB поможет, но основной проблемой является ваш запрос.

От 150 до 200 записей очень много. MySQL поддерживает хранимые процедуры, но для этого вам это не понадобится. Вставки не являются ресурсоемкими, но многие из них сразу или последовательно (используйте синтаксис большого вставки) могут вызвать проблемы.

+0

Я знаю, что мой стол - InnoDB. В какой-то момент может быть объемная вставка, в зависимости от количества уведомлений, которые я должен обновить, так что это, вероятно, то, что происходит. – JohnathanKong

1

Попробуйте это:

SELECT id, " . $userId . ", 'admin_events', 0, event_start_time 
    FROM admin_events AS ae 
    LEFT JOIN admin_event_registrations AS aer 
    ON ae.id = aer.event_id 
    LEFT JOIN admin_event_declines AS aed 
    ON ae.id = aed.event_id 
    WHERE aed.user_id = ". $userid ." 
    AND aer.user_id = ". $userid ." 
    AND aed.id IS NULL 
    AND aer.id IS NULL 
    AND CURDATE() < ae.event_start_time 
    AND ae.event_capacity > ( 
     SELECT SUM(IF(aer2.event_id IS NOT NULL, 1, 0)) 
     FROM admin_event_registrations aer2 
     JOIN admin_events AS ae2 
     ON aer2.event_id = ae2.id 
     WHERE aer2.user_id = ". $userid .") 
    LIMIT 1 

Он по-прежнему имеет подзапрос, но вы увидите, что это намного быстрее, чем другие варианты данных. MySQL может легко присоединяться к таблицам (все они должны быть одного типа таблиц). Кроме того, последнее выражение счетчика не будет отвечать так, как вы хотите, чтобы оно имело нулевые результаты, если вы не обрабатываете нулевые значения. Все это можно сделать в одно мгновение, и с заявлениями о соединении это должно значительно сократить общее время запроса.

+0

Это было бы идеально, но, к сожалению, все таблицы имеют разные поля и не имеют ссылки друг на друга. Помните, что это система уведомлений, поэтому она показывает такие вещи, как новые пользователи, уведомления от администраторов, события, рефералы и т. Д. – JohnathanKong