diff --git a/pkg/services/dashboards/database/database.go b/pkg/services/dashboards/database/database.go
index 9169581424e..a6b5725f68b 100644
--- a/pkg/services/dashboards/database/database.go
+++ b/pkg/services/dashboards/database/database.go
@@ -847,12 +847,22 @@ func (d *dashboardStore) deleteAlertDefinition(dashboardId int64, sess *db.Sessi
 func (d *dashboardStore) GetDashboard(ctx context.Context, query *dashboards.GetDashboardQuery) (*dashboards.Dashboard, error) {
 	var queryResult *dashboards.Dashboard
 	err := d.store.WithDbSession(ctx, func(sess *db.Session) error {
-		if query.ID == 0 && len(query.Slug) == 0 && len(query.UID) == 0 {
+		if query.ID == 0 && len(query.UID) == 0 && (query.Title == nil || query.FolderID == nil) {
 			return dashboards.ErrDashboardIdentifierNotSet
 		}
 
-		dashboard := dashboards.Dashboard{Slug: query.Slug, OrgID: query.OrgID, ID: query.ID, UID: query.UID}
-		has, err := sess.Get(&dashboard)
+		dashboard := dashboards.Dashboard{OrgID: query.OrgID, ID: query.ID, UID: query.UID}
+		mustCols := []string{}
+		if query.Title != nil {
+			dashboard.Title = *query.Title
+			mustCols = append(mustCols, "title")
+		}
+		if query.FolderID != nil {
+			dashboard.FolderID = *query.FolderID
+			mustCols = append(mustCols, "folder_id")
+		}
+
+		has, err := sess.MustCols(mustCols...).Get(&dashboard)
 
 		if err != nil {
 			return err
diff --git a/pkg/services/dashboards/database/database_test.go b/pkg/services/dashboards/database/database_test.go
index 11265a95267..e5a4ba40581 100644
--- a/pkg/services/dashboards/database/database_test.go
+++ b/pkg/services/dashboards/database/database_test.go
@@ -8,11 +8,11 @@ import (
 	"testing"
 	"time"
 
-	"github.com/grafana/grafana/pkg/expr"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 
 	"github.com/grafana/grafana/pkg/components/simplejson"
+	"github.com/grafana/grafana/pkg/expr"
 	"github.com/grafana/grafana/pkg/infra/db"
 	"github.com/grafana/grafana/pkg/services/dashboards"
 	"github.com/grafana/grafana/pkg/services/org"
@@ -23,6 +23,7 @@ import (
 	"github.com/grafana/grafana/pkg/services/tag/tagimpl"
 	"github.com/grafana/grafana/pkg/services/user"
 	"github.com/grafana/grafana/pkg/setting"
+	"github.com/grafana/grafana/pkg/util"
 )
 
 func TestIntegrationDashboardDataAccess(t *testing.T) {
@@ -81,11 +82,12 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
 		require.False(t, queryResult.IsFolder)
 	})
 
-	t.Run("Should be able to get dashboard by slug", func(t *testing.T) {
+	t.Run("Should be able to get dashboard by title and folderID", func(t *testing.T) {
 		setup()
 		query := dashboards.GetDashboardQuery{
-			Slug:  "test-dash-23",
-			OrgID: 1,
+			Title:    util.Pointer("test dash 23"),
+			FolderID: &savedFolder.ID,
+			OrgID:    1,
 		}
 
 		queryResult, err := dashboardStore.GetDashboard(context.Background(), &query)
@@ -98,6 +100,29 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
 		require.False(t, queryResult.IsFolder)
 	})
 
+	t.Run("Should not be able to get dashboard by title alone", func(t *testing.T) {
+		setup()
+		query := dashboards.GetDashboardQuery{
+			Title: util.Pointer("test dash 23"),
+			OrgID: 1,
+		}
+
+		_, err := dashboardStore.GetDashboard(context.Background(), &query)
+		require.ErrorIs(t, err, dashboards.ErrDashboardIdentifierNotSet)
+	})
+
+	t.Run("Folder=0 should not be able to get a dashboard in a folder", func(t *testing.T) {
+		setup()
+		query := dashboards.GetDashboardQuery{
+			Title:    util.Pointer("test dash 23"),
+			FolderID: util.Pointer(int64(0)),
+			OrgID:    1,
+		}
+
+		_, err := dashboardStore.GetDashboard(context.Background(), &query)
+		require.ErrorIs(t, err, dashboards.ErrDashboardNotFound)
+	})
+
 	t.Run("Should be able to get dashboard by uid", func(t *testing.T) {
 		setup()
 		query := dashboards.GetDashboardQuery{
diff --git a/pkg/services/dashboards/models.go b/pkg/services/dashboards/models.go
index bc57eb36ae4..5495c33e5e5 100644
--- a/pkg/services/dashboards/models.go
+++ b/pkg/services/dashboards/models.go
@@ -233,11 +233,25 @@ type DeleteOrphanedProvisionedDashboardsCommand struct {
 // QUERIES
 //
 
+// GetDashboardQuery is used to query for a single dashboard matching
+// a unique constraint within the provided OrgID.
+//
+// Available constraints:
+//   - ID uses Grafana's internal numeric database identifier to get a
+//     dashboard.
+//   - UID use the unique identifier to get a dashboard.
+//   - Title + FolderID uses the combination of the dashboard's
+//     human-readable title and its parent folder's ID
+//     (or zero, for top level items). Both are required if no other
+//     constraint is set.
+//
+// Multiple constraints can be combined.
 type GetDashboardQuery struct {
-	Slug  string // required if no ID or Uid is specified
-	ID    int64  // optional if slug is set
-	UID   string // optional if slug is set
-	OrgID int64
+	ID       int64
+	UID      string
+	Title    *string
+	FolderID *int64
+	OrgID    int64
 }
 
 type DashboardTagCloudItem struct {
diff --git a/pkg/services/provisioning/alerting/rules_provisioner.go b/pkg/services/provisioning/alerting/rules_provisioner.go
index 36fdbef76ea..7abc00f37e2 100644
--- a/pkg/services/provisioning/alerting/rules_provisioner.go
+++ b/pkg/services/provisioning/alerting/rules_provisioner.go
@@ -6,7 +6,6 @@ import (
 	"fmt"
 
 	"github.com/grafana/grafana/pkg/infra/log"
-	"github.com/grafana/grafana/pkg/infra/slugify"
 	"github.com/grafana/grafana/pkg/services/dashboards"
 	alert_models "github.com/grafana/grafana/pkg/services/ngalert/models"
 	"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
@@ -97,8 +96,9 @@ func (prov *defaultAlertRuleProvisioner) provisionRule(
 func (prov *defaultAlertRuleProvisioner) getOrCreateFolderUID(
 	ctx context.Context, folderName string, orgID int64) (string, error) {
 	cmd := &dashboards.GetDashboardQuery{
-		Slug:  slugify.Slugify(folderName),
-		OrgID: orgID,
+		Title:    &folderName,
+		FolderID: util.Pointer(int64(0)),
+		OrgID:    orgID,
 	}
 	cmdResult, err := prov.dashboardService.GetDashboard(ctx, cmd)
 	if err != nil && !errors.Is(err, dashboards.ErrDashboardNotFound) {
diff --git a/pkg/services/provisioning/dashboards/file_reader.go b/pkg/services/provisioning/dashboards/file_reader.go
index b2900b696d3..26d00d18e51 100644
--- a/pkg/services/provisioning/dashboards/file_reader.go
+++ b/pkg/services/provisioning/dashboards/file_reader.go
@@ -13,7 +13,6 @@ import (
 
 	"github.com/grafana/grafana/pkg/components/simplejson"
 	"github.com/grafana/grafana/pkg/infra/log"
-	"github.com/grafana/grafana/pkg/infra/slugify"
 	"github.com/grafana/grafana/pkg/services/accesscontrol"
 	"github.com/grafana/grafana/pkg/services/dashboards"
 	"github.com/grafana/grafana/pkg/services/provisioning/utils"
@@ -299,7 +298,11 @@ func (fr *FileReader) getOrCreateFolderID(ctx context.Context, cfg *config, serv
 		return 0, ErrFolderNameMissing
 	}
 
-	cmd := &dashboards.GetDashboardQuery{Slug: slugify.Slugify(folderName), OrgID: cfg.OrgID}
+	cmd := &dashboards.GetDashboardQuery{
+		Title:    &folderName,
+		FolderID: util.Pointer(int64(0)),
+		OrgID:    cfg.OrgID,
+	}
 	result, err := fr.dashboardStore.GetDashboard(ctx, cmd)
 
 	if err != nil && !errors.Is(err, dashboards.ErrDashboardNotFound) {