Я не эксперт по MySQL, но похоже, что первичные ключи MySQL кластеризованы - вам нужно убедиться, что это так с первичными ключами; кластерные индексы определенно помогут ускорить процесс.
Хотя, одна вещь - я не верю, что у вас может быть два "первичных" ключа на любой таблице; Ваша таблица URL выглядит довольно подозрительно для меня по этой причине. Прежде всего, вы должны быть абсолютно уверены, что эти два столбца в таблице URL-адресов проиндексированы с рукояткой - отдельный числовой индекс для каждого должен быть в порядке - потому что вы присоединяетесь к ним, поэтому СУБД должна знать, как найти их быстро; это может быть то, что происходит в вашем случае. Если вы сканируете столько строк в полном объеме, то да, вы могли бы сидеть там довольно долго, пока сервер пытается найти все, что вы просили.
Я бы также предложил удалить эту функцию CONCAT из оператора select и посмотреть, как это повлияет на ваши результаты. Я был бы удивлен, если бы это не способствовало так или иначе. Просто извлеките оба столбца, а затем обработайте конкатенацию и посмотрите, как это происходит.
Наконец, вы выяснили, где находится узкое место? Простое объединение в три таблицы по несколько миллионов строк не займет много времени (я мог бы ожидать секунды или около того, просто просматривая таблицы и запросы), при условии правильной индексации таблиц. Но если вы перемещаете эти строки по медленной или уже привязанной сетевой карте, на сервер приложений с нехваткой памяти и т. Д., Медлительность может вообще не иметь никакого отношения к вашему запросу, а вместо этого к тому, что происходит после запроса. Семь миллионов строк - это довольно много данных для сборки и перемещения, независимо от того, сколько времени займет поиск этих строк. Попробуйте выбрать только одну строку, а не все семь миллионов, и посмотрите, как это выглядит в отличие. Если это быстро, то проблема не в запросе, а в наборе результатов.