Optimize SQL queries
This commit is contained in:
parent
5bcfd02974
commit
8cd72bd377
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="results-filter-button" (click)="isSearchFilterCollapsed = !isSearchFilterCollapsed" role="button"
|
class="results-filter-button" (click)="isSearchFilterCollapsed = !isSearchFilterCollapsed" role="button"
|
||||||
[attr.aria-expanded]="isSearchFilterCollapsed" aria-controls="collapseBasic"
|
[attr.aria-expanded]="!isSearchFilterCollapsed" aria-controls="collapseBasic"
|
||||||
>
|
>
|
||||||
<span class="icon icon-filter"></span>
|
<span class="icon icon-filter"></span>
|
||||||
<ng-container i18n>Filters</ng-container>
|
<ng-container i18n>Filters</ng-container>
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="results-filter" [collapse]="isSearchFilterCollapsed">
|
<div class="results-filter" [collapse]="isSearchFilterCollapsed">
|
||||||
<my-search-filters [advancedSearch]="advancedSearch" (filtered)="onFiltered($event)"></my-search-filters>
|
<my-search-filters [advancedSearch]="advancedSearch" (filtered)="onFiltered()"></my-search-filters>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ let config: IConfig = require('config')
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
const LAST_MIGRATION_VERSION = 230
|
const LAST_MIGRATION_VERSION = 235
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import * as Sequelize from 'sequelize'
|
||||||
|
import { createClient } from 'redis'
|
||||||
|
import { CONFIG } from '../constants'
|
||||||
|
import { JobQueue } from '../../lib/job-queue'
|
||||||
|
import { initDatabaseModels } from '../database'
|
||||||
|
|
||||||
|
async function up (utils: {
|
||||||
|
transaction: Sequelize.Transaction
|
||||||
|
queryInterface: Sequelize.QueryInterface
|
||||||
|
sequelize: Sequelize.Sequelize
|
||||||
|
}): Promise<any> {
|
||||||
|
await utils.sequelize.query('DROP INDEX IF EXISTS video_id_privacy_state_wait_transcoding;')
|
||||||
|
await utils.sequelize.query('DROP INDEX IF EXISTS video_name;')
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
const query = 'DELETE FROM "videoFile" WHERE id IN ' +
|
||||||
|
'(SELECT id FROM (SELECT MIN(id) AS id, "videoId", "resolution", "fps" ' +
|
||||||
|
'FROM "videoFile" GROUP BY "videoId", "resolution", "fps" HAVING COUNT(*) > 1) t)'
|
||||||
|
await utils.sequelize.query(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
const query = 'DELETE FROM "actor" WHERE id IN ' +
|
||||||
|
'(SELECT id FROM (SELECT MIN(id) AS id, "uuid" ' +
|
||||||
|
'FROM "actor" GROUP BY "uuid" HAVING COUNT(*) > 1) t)'
|
||||||
|
await utils.sequelize.query(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
const query = 'DELETE FROM "account" WHERE id IN ' +
|
||||||
|
'(SELECT id FROM (SELECT MIN(id) AS id, "actorId" ' +
|
||||||
|
'FROM "account" GROUP BY "actorId" HAVING COUNT(*) > 1) t)'
|
||||||
|
await utils.sequelize.query(query)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function down (options) {
|
||||||
|
throw new Error('Not implemented.')
|
||||||
|
}
|
||||||
|
|
||||||
|
export { up, down }
|
|
@ -17,6 +17,15 @@ import { ActorModel } from '../activitypub/actor'
|
||||||
{
|
{
|
||||||
fields: [ 'videoId', 'accountId' ],
|
fields: [ 'videoId', 'accountId' ],
|
||||||
unique: true
|
unique: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: [ 'videoId' ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: [ 'accountId' ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: [ 'videoId', 'type' ]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
|
@ -46,7 +46,19 @@ import { UserModel } from './user'
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'account'
|
tableName: 'account',
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
fields: [ 'actorId' ],
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: [ 'applicationId' ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: [ 'userId' ]
|
||||||
|
}
|
||||||
|
]
|
||||||
})
|
})
|
||||||
export class AccountModel extends Model<AccountModel> {
|
export class AccountModel extends Model<AccountModel> {
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,8 @@ enum ScopeNames {
|
||||||
tableName: 'actor',
|
tableName: 'actor',
|
||||||
indexes: [
|
indexes: [
|
||||||
{
|
{
|
||||||
fields: [ 'url' ]
|
fields: [ 'url' ],
|
||||||
|
unique: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fields: [ 'preferredUsername', 'serverId' ],
|
fields: [ 'preferredUsername', 'serverId' ],
|
||||||
|
@ -94,6 +95,13 @@ enum ScopeNames {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fields: [ 'avatarId' ]
|
fields: [ 'avatarId' ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: [ 'uuid' ],
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: [ 'followersUrl' ]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
|
@ -68,6 +68,9 @@ enum ScopeNames {
|
||||||
indexes: [
|
indexes: [
|
||||||
{
|
{
|
||||||
fields: [ 'accountId' ]
|
fields: [ 'accountId' ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: [ 'actorId' ]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
|
@ -108,6 +108,9 @@ enum ScopeNames {
|
||||||
{
|
{
|
||||||
fields: [ 'url' ],
|
fields: [ 'url' ],
|
||||||
unique: true
|
unique: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: [ 'accountId' ]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,6 +18,10 @@ import { VideoModel } from './video'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fields: [ 'infoHash' ]
|
fields: [ 'infoHash' ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: [ 'videoId', 'resolution', 'fps' ],
|
||||||
|
unique: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
|
@ -99,26 +99,22 @@ import { VideosSearchQuery } from '../../../shared/models/search'
|
||||||
const indexes: Sequelize.DefineIndexesOptions[] = [
|
const indexes: Sequelize.DefineIndexesOptions[] = [
|
||||||
buildTrigramSearchIndex('video_name_trigram', 'name'),
|
buildTrigramSearchIndex('video_name_trigram', 'name'),
|
||||||
|
|
||||||
|
{ fields: [ 'createdAt' ] },
|
||||||
|
{ fields: [ 'publishedAt' ] },
|
||||||
|
{ fields: [ 'duration' ] },
|
||||||
|
{ fields: [ 'category' ] },
|
||||||
|
{ fields: [ 'licence' ] },
|
||||||
|
{ fields: [ 'nsfw' ] },
|
||||||
|
{ fields: [ 'language' ] },
|
||||||
|
{ fields: [ 'waitTranscoding' ] },
|
||||||
|
{ fields: [ 'state' ] },
|
||||||
|
{ fields: [ 'remote' ] },
|
||||||
|
{ fields: [ 'views' ] },
|
||||||
|
{ fields: [ 'likes' ] },
|
||||||
|
{ fields: [ 'channelId' ] },
|
||||||
{
|
{
|
||||||
fields: [ 'createdAt' ]
|
fields: [ 'uuid' ],
|
||||||
},
|
unique: true
|
||||||
{
|
|
||||||
fields: [ 'duration' ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fields: [ 'views' ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fields: [ 'likes' ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fields: [ 'uuid' ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fields: [ 'channelId' ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fields: [ 'id', 'privacy', 'state', 'waitTranscoding' ]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fields: [ 'url'],
|
fields: [ 'url'],
|
||||||
|
@ -212,16 +208,16 @@ type AvailableForListOptions = {
|
||||||
),
|
),
|
||||||
[ Sequelize.Op.in ]: Sequelize.literal(
|
[ Sequelize.Op.in ]: Sequelize.literal(
|
||||||
'(' +
|
'(' +
|
||||||
'SELECT "videoShare"."videoId" AS "id" FROM "videoShare" ' +
|
'SELECT "videoShare"."videoId" AS "id" FROM "videoShare" ' +
|
||||||
'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "videoShare"."actorId" ' +
|
'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "videoShare"."actorId" ' +
|
||||||
'WHERE "actorFollow"."actorId" = ' + actorIdNumber +
|
'WHERE "actorFollow"."actorId" = ' + actorIdNumber +
|
||||||
' UNION ' +
|
' UNION ' +
|
||||||
'SELECT "video"."id" AS "id" FROM "video" ' +
|
'SELECT "video"."id" AS "id" FROM "video" ' +
|
||||||
'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' +
|
'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' +
|
||||||
'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' +
|
'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' +
|
||||||
'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' +
|
'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' +
|
||||||
'LEFT JOIN "actorFollow" ON "actorFollow"."targetActorId" = "actor"."id" ' +
|
'WHERE "actor"."serverId" IS NULL OR ' +
|
||||||
'WHERE "actor"."serverId" IS NULL OR "actorFollow"."actorId" = ' + actorIdNumber +
|
'"actor"."id" IN (SELECT "targetActorId" FROM "actorFollow" WHERE "actorId" = 1)' + // Subquery for optimization
|
||||||
')'
|
')'
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue