Remove usages of FIND_IN_SET
FIND_IN_SET doesn't make use of indexes
This commit is contained in:
@ -72,55 +72,60 @@ pub async fn get_reminders(
|
||||
|
||||
match channels_res {
|
||||
Ok(channels) => {
|
||||
let channels = channels
|
||||
.keys()
|
||||
.into_iter()
|
||||
.map(|k| k.get().to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(",");
|
||||
let channels =
|
||||
channels.keys().into_iter().map(|k| k.get().to_string()).collect::<Vec<String>>();
|
||||
|
||||
sqlx::query_as_unchecked!(
|
||||
GetReminder,
|
||||
let placeholder = vec!["?"; channels.len()].join(",");
|
||||
let sql = format!(
|
||||
"
|
||||
SELECT
|
||||
reminders.attachment_name,
|
||||
reminders.avatar,
|
||||
channels.channel,
|
||||
reminders.content,
|
||||
reminders.embed_author,
|
||||
reminders.embed_author_url,
|
||||
reminders.embed_color,
|
||||
reminders.embed_description,
|
||||
reminders.embed_footer,
|
||||
reminders.embed_footer_url,
|
||||
reminders.embed_image_url,
|
||||
reminders.embed_thumbnail_url,
|
||||
reminders.embed_title,
|
||||
IFNULL(reminders.embed_fields, '[]') AS embed_fields,
|
||||
reminders.enabled,
|
||||
reminders.expires,
|
||||
reminders.interval_seconds,
|
||||
reminders.interval_days,
|
||||
reminders.interval_months,
|
||||
reminders.name,
|
||||
reminders.restartable,
|
||||
reminders.tts,
|
||||
reminders.uid,
|
||||
reminders.username,
|
||||
reminders.utc_time
|
||||
reminders.attachment_name,
|
||||
reminders.avatar,
|
||||
channels.channel,
|
||||
reminders.content,
|
||||
reminders.embed_author,
|
||||
reminders.embed_author_url,
|
||||
reminders.embed_color,
|
||||
reminders.embed_description,
|
||||
reminders.embed_footer,
|
||||
reminders.embed_footer_url,
|
||||
reminders.embed_image_url,
|
||||
reminders.embed_thumbnail_url,
|
||||
reminders.embed_title,
|
||||
IFNULL(reminders.embed_fields, '[]') AS embed_fields,
|
||||
reminders.enabled,
|
||||
reminders.expires,
|
||||
reminders.interval_seconds,
|
||||
reminders.interval_days,
|
||||
reminders.interval_months,
|
||||
reminders.name,
|
||||
reminders.restartable,
|
||||
reminders.tts,
|
||||
reminders.uid,
|
||||
reminders.username,
|
||||
reminders.utc_time
|
||||
FROM reminders
|
||||
INNER JOIN channels ON channels.id = reminders.channel_id
|
||||
WHERE `status` = 'pending' AND FIND_IN_SET(channels.channel, ?)",
|
||||
channels
|
||||
)
|
||||
.fetch_all(pool.inner())
|
||||
.await
|
||||
.map(|r| Ok(json!(r)))
|
||||
.unwrap_or_else(|e| {
|
||||
warn!("Failed to complete SQL query: {:?}", e);
|
||||
INNER JOIN channels
|
||||
ON channels.id = reminders.channel_id
|
||||
WHERE `status` = 'pending'
|
||||
AND channels.channel IN ({placeholder})
|
||||
"
|
||||
);
|
||||
|
||||
json_err!("Could not load reminders")
|
||||
})
|
||||
let mut query = sqlx::query_as::<Database, GetReminder>(&sql);
|
||||
for channel in channels {
|
||||
query = query.bind(channel);
|
||||
}
|
||||
|
||||
query
|
||||
.fetch_all(pool.inner())
|
||||
.await
|
||||
.map(|reminders| Ok(json!(reminders)))
|
||||
.unwrap_or_else(|e| {
|
||||
warn!("Failed to complete SQL query: {:?}", e);
|
||||
|
||||
json_err!("Could not load reminders")
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Could not fetch channels from {}: {:?}", id, e);
|
||||
|
@ -1,3 +1,14 @@
|
||||
use crate::web::{
|
||||
check_authorization,
|
||||
guards::transaction::Transaction,
|
||||
routes::{
|
||||
dashboard::{
|
||||
create_reminder, CreateReminder, ImportBody, ReminderCsv, ReminderTemplateCsv, TodoCsv,
|
||||
},
|
||||
JsonResult,
|
||||
},
|
||||
};
|
||||
use crate::Database;
|
||||
use base64::{prelude::BASE64_STANDARD, Engine};
|
||||
use csv::{QuoteStyle, WriterBuilder};
|
||||
use log::warn;
|
||||
@ -14,17 +25,6 @@ use serenity::{
|
||||
};
|
||||
use sqlx::{MySql, Pool};
|
||||
|
||||
use crate::web::{
|
||||
check_authorization,
|
||||
guards::transaction::Transaction,
|
||||
routes::{
|
||||
dashboard::{
|
||||
create_reminder, CreateReminder, ImportBody, ReminderCsv, ReminderTemplateCsv, TodoCsv,
|
||||
},
|
||||
JsonResult,
|
||||
},
|
||||
};
|
||||
|
||||
#[get("/api/guild/<id>/export/reminders")]
|
||||
pub async fn export_reminders(
|
||||
id: u64,
|
||||
@ -40,48 +40,47 @@ pub async fn export_reminders(
|
||||
|
||||
match channels_res {
|
||||
Ok(channels) => {
|
||||
let channels = channels
|
||||
.keys()
|
||||
.into_iter()
|
||||
.map(|k| k.get().to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(",");
|
||||
|
||||
let result = sqlx::query_as_unchecked!(
|
||||
ReminderCsv,
|
||||
"SELECT
|
||||
reminders.attachment,
|
||||
reminders.attachment_name,
|
||||
reminders.avatar,
|
||||
CONCAT('#', channels.channel) AS channel,
|
||||
reminders.content,
|
||||
reminders.embed_author,
|
||||
reminders.embed_author_url,
|
||||
reminders.embed_color,
|
||||
reminders.embed_description,
|
||||
reminders.embed_footer,
|
||||
reminders.embed_footer_url,
|
||||
reminders.embed_image_url,
|
||||
reminders.embed_thumbnail_url,
|
||||
reminders.embed_title,
|
||||
reminders.embed_fields,
|
||||
reminders.enabled,
|
||||
reminders.expires,
|
||||
reminders.interval_seconds,
|
||||
reminders.interval_days,
|
||||
reminders.interval_months,
|
||||
reminders.name,
|
||||
reminders.restartable,
|
||||
reminders.tts,
|
||||
reminders.username,
|
||||
reminders.utc_time
|
||||
let channels =
|
||||
channels.keys().into_iter().map(|k| k.get().to_string()).collect::<Vec<String>>();
|
||||
let placeholder = vec!["?"; channels.len()].join(",");
|
||||
let sql = format!(
|
||||
"
|
||||
SELECT
|
||||
reminders.attachment,
|
||||
reminders.attachment_name,
|
||||
reminders.avatar,
|
||||
CONCAT('#', channels.channel) AS channel,
|
||||
reminders.content,
|
||||
reminders.embed_author,
|
||||
reminders.embed_author_url,
|
||||
reminders.embed_color,
|
||||
reminders.embed_description,
|
||||
reminders.embed_footer,
|
||||
reminders.embed_footer_url,
|
||||
reminders.embed_image_url,
|
||||
reminders.embed_thumbnail_url,
|
||||
reminders.embed_title,
|
||||
reminders.embed_fields,
|
||||
reminders.enabled,
|
||||
reminders.expires,
|
||||
reminders.interval_seconds,
|
||||
reminders.interval_days,
|
||||
reminders.interval_months,
|
||||
reminders.name,
|
||||
reminders.restartable,
|
||||
reminders.tts,
|
||||
reminders.username,
|
||||
reminders.utc_time
|
||||
FROM reminders
|
||||
LEFT JOIN channels ON channels.id = reminders.channel_id
|
||||
WHERE FIND_IN_SET(channels.channel, ?) AND status = 'pending'",
|
||||
channels
|
||||
)
|
||||
.fetch_all(pool.inner())
|
||||
.await;
|
||||
LEFT JOIN channels
|
||||
ON channels.id = reminders.channel_id
|
||||
WHERE status = 'pending'
|
||||
AND channels.channel IN ({placeholder})
|
||||
"
|
||||
);
|
||||
|
||||
let result =
|
||||
sqlx::query_as::<Database, ReminderCsv>(&sql).fetch_all(pool.inner()).await;
|
||||
|
||||
match result {
|
||||
Ok(reminders) => {
|
||||
|
@ -17,6 +17,7 @@ use serenity::{
|
||||
model::id::{ChannelId, GuildId, UserId},
|
||||
};
|
||||
use sqlx::types::Json;
|
||||
use sqlx::FromRow;
|
||||
|
||||
use crate::web::{
|
||||
catchers::internal_server_error,
|
||||
@ -177,7 +178,7 @@ pub struct CreateReminder {
|
||||
utc_time: NaiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, FromRow)]
|
||||
pub struct GetReminder {
|
||||
attachment_name: Option<String>,
|
||||
avatar: Option<String>,
|
||||
@ -209,7 +210,7 @@ pub struct GetReminder {
|
||||
utc_time: NaiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, FromRow)]
|
||||
pub struct ReminderCsv {
|
||||
attachment: Option<Attachment>,
|
||||
attachment_name: Option<String>,
|
||||
|
Reference in New Issue
Block a user