Запрос ниже блокирует общий хост с ошибкой
SQLSTATE[HY000]: General error: 2013 Lost connection to MySQL server during query
Этот запрос представляет собой версию Symfony / Doctrine более крупного запроса с использованием простого PHP, который я перемещаю по Symfony / Doctrine. Я уже разрезал его на 8 небольших запросов, но все еще сталкиваюсь с той же проблемой.
Обратите внимание, что исходный огромный запрос выполняется на одном и том же общем хосте без сбоев.
php.ini max_execution_time установлен на 60, что должно быть более чем достаточно.
Также обратите внимание, что на моем локальном сервере этот запрос имеет тактовую частоту около 1 мс, согласно профилировщику Symfony. Это очень похоже на тот же диапазон, что и другие 7 аналогичных запросов.
Предложения WHERE и GROUP BY одинаковы для всех 8 указанных запросов, так что это не должно быть проблемой.
Любые идеи?
$query = $this->getEntityManager()
->createQuery(
"SELECT v.id AS version_id,
pr.price AS price,
mt.power AS mpower,
ms.trunk AS trunk
FROM AppBundle:Version v
JOIN v.prices pr
JOIN v.motor mt
JOIN v.measure ms
WHERE v.id IN (:version_ids)
GROUP BY v.id
ORDER BY pr.price"
)
->setParameter('version_ids', $version_ids);
Краткое изложение сущностей выглядит так:
/src/AppBundle/Entity/Version.php
/**
* @ORM\Entity(repositoryClass = "AppBundle\Repository\VersionRepository")
* @ORM\Table(name = "versions")
*/
class Version
{
/**
* @var integer
*
* @ORM\Id
* @ORM\Column(type = "smallint",length=4,unique=true,options = {"unsigned":true})
* @ORM\GeneratedValue(strategy = "AUTO")
*/
protected $id;
.....
/**
* Many versions have One motor.
* @ORM\ManyToOne(targetEntity = "Motor")
* @ORM\JoinColumn(name = "motor_id", referencedColumnName = "id")
*/
private $motor;
/**
* Many versions have One set of measures.
* @ORM\ManyToOne(targetEntity = "Measure")
* @ORM\JoinColumn(name = "measure_id", referencedColumnName = "id")
*/
private $measure;
...
/src/AppBundle/Entity/Price.php
class Price
{
/**
* @ORM\Id
* @ORM\OneToOne(targetEntity = "Version", inversedBy = "prices")
*/
private $version;
...
/src/AppBundle/Entity/Measure.php
class Measure
{
/**
* @var integer
*
* @ORM\Id
* @ORM\Column(type = "smallint",length=4,unique=true,options = {"unsigned":true})
* @ORM\GeneratedValue(strategy = "AUTO")
*/
protected $id;
...
/src/AppBundle/Entity/Motor.php
class Motor
{
/**
* @var integer
*
* @ORM\Id
* @ORM\Column(type = "smallint",length=4,unique=true,options = {"unsigned":true})
* @ORM\GeneratedValue(strategy = "AUTO")
*/
protected $id;
....
Обновлено: ОБЪЯСНИТЬ ВЫБРАТЬ результат:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE v0_ range PRIMARY,UNIQ_,IDX_1 PRIMARY 2 NULL 5 Using where; Using temporary; Using filesort
1 SIMPLE p1_ eq_ref PRIMARY PRIMARY 2 v0_.id 1 NULL
1 SIMPLE m2_ eq_ref PRIMARY,UNIQ_ PRIMARY 2 v0_.motor_id 1 NULL
1 SIMPLE m3_ eq_ref PRIMARY,UNIQ_ PRIMARY 2 v0_.measure_id 1 NULL
SHOW WARNINGS просто возвращается с Level = Note и Code = 1003, который, насколько я понимаю, должен быть обычным кодом EXPLAIN EXTENDED.
Поскольку вы упомянули, что это общий хост, может быть, ваше соединение mysql ограничено в потреблении ресурсов (например, сколько оперативной памяти оно может занять)? Каков порядок количества наборов результатов?
@JovanPerovic. Всегда есть предел, и, будучи общим хостом, он определенно не так высок. Вопрос в том, почему он позволяет выполнять очень сложный запрос, исходящий от простого PHP, но блокирует сравнительно более простой запрос, созданный Doctrine? Есть ли что-то изначально неэффективное в этом запросе или базовой конфигурации таблицы? Не должно быть последнего, поскольку структуры таблиц идентичны.
Это может быть гидратация, хотя связь ToMany не связана. Сколько версий version_ids?
Таблицы версий и цен содержат около 2000 строк, а размеры и двигатели - менее 1000 строк.
@lxg, спасибо, я добавил к своему вопросу вывод SELECT EXPLAIN и SHOW WARNINGS. Ничто не кажется мне необычным, но, может быть, я чего-то упускаю.
Попробуйте ограничить свои результаты, например "$ query-> setMaxResults (100);" Вы все еще получаете ошибку?






Вы можете позволить Doctrine отображать сгенерированный SQL с помощью
$this->getEntityManager()->createQuery()->getSQL();и попробовать запустить его на сервере MySQL из командной строки. Конечно, Doctrine предоставит вам один из своих нечитаемых SQL-запросов, но даже запуск его на сервере и, возможно, немного поработать сEXPLAIN SELECTилиSHOW WARNINGSможет вам помочь. Или попробуйте изменить запрос, чтобы посмотреть, можно ли изолировать проблему.