2016-08-10 2 views
2

Я использую PHP-Mysql для своего проекта, и у меня есть таблица с более чем 30000 строк.Как ускорить запрос?

Когда мой код доступа к этой таблице, запросите время слишком долго.

Как я могу получить больше скорости? или каким-то образом сделать это?

Я использую Laravel 5.1. Мой код, как это (не беспокойтесь о правильной или нет):

Games::join('categories', 'categories.id_game', '=', 'games.id')->where('games.id', $id) 
->select('games.*', 'categories.name')->get()->toArray(); 

Таблица Games имеет более 30000 строк, и я использовал index (идентификатор) для таблицы Games.

Обновлено: Мне просто нужно 1 ~ 300 записей сразу. Но запрос запроса слишком длинный. Я думаю, что проблема из таблицы games имеет столько строк. Я нахожу решение для этого. Я пробовал как-то: установил index для таблицы games, просто выберите поле (название игры, название категории), что мне нужно.

Извините за мой английский!

+0

Зачем вам нужно использовать -> select(), если вы можете делать Игры :: где ('id', $ id) -> get() -> toArray(); –

+0

@JohnRoca Извините, я часто не использую -> select(). Я просто выбираю(), когда хочу выделить какое-то поле в таблице. Вопрос обновлен –

+4

Почему вы возвращаете 30000 строк, это настоящий вопрос? – Ohgodwhy

ответ

3
  1. Вам действительно нужны 3000 записей сразу? Подумайте о разбиении на страницы/разбиении на части.
  2. В моделях Laravel $ visible и $ hidden атрибут, определяющий столбцы для сериализации.
protected $visible = ['id', 'name', 'age']; 

Если вы сериализовать модель по ToArray() или toJson() метод, вы можете получить только ту информацию, которую вы хотите.

+0

Спасибо за ответ! Мне просто нужно 1 ~ 300 записей сразу. Но запрос запроса слишком длинный. Я думаю, что проблема из таблицы 'games' имеет столько строк. –

+0

Попробуйте использовать ** skip ** и ** take ** метод как ограничение вашего запроса: '$ users = DB :: table ('users') -> skip (10) -> take (5) -> get(); ' – miikes

1
  1. Использовать разбивку на страницы, как предложено @miikes выше.

  2. id_game в категориях также индексируется таблица? если не индексировать это тоже.

  3. при использовании Mysql Workbench попытайтесь просмотреть план выполнения и соответствующим образом настроить.

+0

Спасибо за ответ! Я стараюсь изо всех сил. –

0

Как другие уже говорил, - скорее всего, два объяснения:

  1. Это занимает много времени для 30000 записей для чтения, передаются, обрабатываются и поместить в массив. (Вероятно, вы также увидите довольно большой объем памяти, который пережевывается PHP ...)

  2. Там что-то отсутствует.

Отсутствие индексов можно идентифицировать с помощью EXPLAIN. Я не буду вдаваться в подробности здесь, вы можете Google it. Сначала я дважды проверяю наличие соответствующих индексов на JOIN.

Но ваш запрос на самом деле очень простой. Таким образом, гораздо более вероятным является «воспринимаемая» продолжительность запроса. MySQL достаточно долго читает все эти записи, помещает их в память, форматирует их, доставляет их по стеку TCP/IP, получает PHP, обрабатывает их в массив и т. Д.

Рассмотрите (как уже говорили другие) с помощью предложения LIMIT, чтобы уменьшить количество возвращенных записей. (Индексированный первичный ключ ORDER BY гарантирует, что вы всегда получите те же результаты для заданного LIMIT.)

Наконец-то (но я подозреваю, что это самый низкий уровень вероятности): мы не можем видеть структуры таблицы. Они очень широкие? Возможно, BLOB или TEXT полей внутри? Если предположить, что средняя запись велика (скажем, 2 КБ), то 30 000 записей будут 58 МБ данных. Возможно, было бы целесообразно кэшировать некоторые более крупные данные поиска в PHP в первую очередь.

Мне также приходит в голову, что вы можете застрять в общем колесе решения проблемы, которая не существует.

Вы возвращаетесь всех, но вы на самом деле с помощью все в коде, который следует? (Вы уже сказали, что вам нужно всего ~ 300 рядов за раз.)

Я работал над некоторыми серьезными большими базами данных (как я уверен, другие люди, отвечающие тоже) - иногда это проблема, которая должна изменение, а не решение.

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

+0

Может быть, вы правы, мой стол имеет поле 'TEXT' с более чем 80 ~ 5000 словами. И мой запрос присоединился к таблице 3 ~ 4, у меня были ограниченные записи - 200. И моя база данных около 90 МБ. –