英文:
Deferred JOIN: can't handle JOIN USING without authoritative tables
问题
I have a basic database in which I'm trying to implement the deferred join technique. However, on Planetscale I keep getting the following error: can't handle JOIN USING without authoritative tables
.
I'm not terribly well-versed in MYSQL, but I'm struggling to understand what might be the issue. Here is a sample query:
SELECT * FROM Articles
INNER JOIN (
SELECT id FROM Story ORDER BY createdAt,id LIMIT 20 OFFSET xxx
) dummy USING (id)
ORDER BY
createdAt,id;
+-----------+-----------------+------+-----+----------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-----------------+------+-----+----------------------+-------------------+
| id | bigint unsigned | NO | PRI | | auto_increment |
| title | varchar(255) | NO | MUL | | |
| synopsis | varchar(2048) | NO | | | |
| createdAt | datetime(3) | NO | MUL | CURRENT_TIMESTAMP(3) | DEFAULT_GENERATED |
| updatedAt | datetime(3) | YES | | | |
| content | mediumtext | NO | MUL | | |
| wordcount | int | NO | | | |
| authorId | int | NO | MUL | | |
+-----------+-----------------+------+-----+----------------------+-------------------+
update, to add show create table
:
CREATE TABLE `Articles` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`synopsis` varchar(2048) COLLATE utf8mb4_unicode_ci NOT NULL,
`createdAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` datetime(3) DEFAULT NULL,
`content` varchar(4) COLLATE utf8mb4_unicode_ci NOT NULL,
`wordcount` tinyint(1) NOT NULL DEFAULT '0',
`authorId` int DEFAULT NULL, PRIMARY KEY(`id`),
KEY `Story_authorId_idx`(`authorId`),
KEY `Story_createdAt_idx`(`createdAt`),
KEY `createdAt`(`createdAt`),
FULLTEXT KEY `Story_title_content_synopsis_idx`(`title`, `content`, `synopsis`),
FULLTEXT KEY `Story_title_idx`(`title`),
FULLTEXT KEY `Story_content_idx`(`content`)
)
ENGINE = InnoDB AUTO_INCREMENT = 7892518284260113982 DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci
I originally generated the schema via Prisma (if that matters), but have since written things/queries natively because of performance issues.
英文:
I have a basic database in which I'm trying to implement the deferred join technique. However, on Planetscale I keep getting the following error: can't handle JOIN USING without authoritative tables
.
I'm not terribly well-versed in MYSQL, but I'm struggling to understand what might be the issue. Here is a sample query:
SELECT * FROM Articles
INNER JOIN (
SELECT id FROM Story ORDER BY createdAt,id LIMIT 20 OFFSET xxx
) dummy USING (id)
ORDER BY
createdAt,id;
+-----------+-----------------+------+-----+----------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-----------------+------+-----+----------------------+-------------------+
| id | bigint unsigned | NO | PRI | | auto_increment |
| title | varchar(255) | NO | MUL | | |
| synopsis | varchar(2048) | NO | | | |
| createdAt | datetime(3) | NO | MUL | CURRENT_TIMESTAMP(3) | DEFAULT_GENERATED |
| updatedAt | datetime(3) | YES | | | |
| content | mediumtext | NO | MUL | | |
| wordcount | int | NO | | | |
| authorId | int | NO | MUL | | |
+-----------+-----------------+------+-----+----------------------+-------------------+
update, to add show create table
:
CREATE TABLE `Articles` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`synopsis` varchar(2048) COLLATE utf8mb4_unicode_ci NOT NULL,
`createdAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` datetime(3) DEFAULT NULL,
`content` varchar(4) COLLATE utf8mb4_unicode_ci NOT NULL,
`wordcount` tinyint(1) NOT NULL DEFAULT '0',
`authorId` int DEFAULT NULL, PRIMARY KEY(`id`),
KEY `Story_authorId_idx`(`authorId`),
KEY `Story_createdAt_idx`(`createdAt`),
KEY `createdAt`(`createdAt`),
FULLTEXT KEY `Story_title_content_synopsis_idx`(`title`, `content`, `synopsis`),
FULLTEXT KEY `Story_title_idx`(`title`),
FULLTEXT KEY `Story_content_idx`(`content`)
)
ENGINE = InnoDB AUTO_INCREMENT = 7892518284260113982 DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci
I originally generated the schema via Prisma (if that matters), but have since written things/queries natively because of performance issues.
答案1
得分: 2
你可以尝试将你的查询重写为等效的 ON <expression>
语法。
这个:
FROM Articles JOIN ( ...) AS dummy USING (id)
可以写成:
FROM Articles JOIN ( ...) AS dummy ON Articles.id = dummy.id
在SQL中,当你使用 USING
语法时,SELECT *
有特殊的行为。*
通配符会扩展到所有列,但已知相等的列只会在结果集中包含一次。
我没有在PlanetScale上进行过测试,所以我不知道PlanetScale是否能处理这个问题。
这个问题声称自2022年5月以来支持USING
:https://github.com/vitessio/vitess/pull/10226 但我没有在那个日期之后的发布说明中找到描述这个功能的内容。如果你更仔细地搜索,可能会有更好的运气。
英文:
You could try rewriting your query to the equivalent ON <expression>
syntax.
This:
FROM Articles JOIN ( ...) AS dummy USING (id)
Can be written as:
FROM Articles JOIN ( ...) AS dummy ON Articles.id = dummy.id
There is special behavior in SQL for SELECT *
when you have the USING
syntax. The *
wildcard expands to all columns, but columns that are known to be equal are included in the result set only once.
I have not tested this with PlanetScale, so I don't know if PlanetScale will handle it or not.
This issue claims that USING
is supported since May 2022: https://github.com/vitessio/vitess/pull/10226 But I didn't find anything in the release notes since that date describing the feature. You may have more luck if you search more thoroughly.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论