diff --git a/NEWS b/NEWS
index e974c0459784e13d400909fcc4f0c69702740851..82b5a23da8dc292ddb044782da7dc7ebb3c0106e 100644
--- a/NEWS
+++ b/NEWS
@@ -222,6 +222,7 @@ documents those changes that are of interest to users and admins.
       options.
  -- when using -j option in sacct no user restriction will applied unless
     specified with the -u option.
+ -- significant speed up for association based reports in sreport
 
 * Changes in SLURM 1.3.13
 =========================
diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
index 4dbb84ac5d72baa09cfc1735487dcde837791936..049770f8fc41079ddd9451524b2ce6e788cb2adf 100644
--- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
+++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
@@ -1226,7 +1226,7 @@ static int _setup_association_cond_limits(acct_association_cond_t *assoc_cond,
 	} else if(assoc_cond->user_list) {
 		/* we want all the users, but no non-user associations */
 		set = 1;
-		xstrfmtcat(*extra, " && (%s.user!='')", prefix);		
+		xstrfmtcat(*extra, " && (%s.user!='')", prefix);
 	}
 
 	if(assoc_cond->partition_list 
@@ -2487,6 +2487,208 @@ static int _get_db_index(MYSQL *db_conn,
 	return db_index;
 }
 
+/* checks should already be done before this to see if this is a valid
+   user or not.
+*/
+static int _get_usage_for_list(mysql_conn_t *mysql_conn,
+			    slurmdbd_msg_type_t type, List object_list, 
+			    time_t start, time_t end)
+{
+#ifdef HAVE_MYSQL
+	int rc = SLURM_SUCCESS;
+	int i=0;
+	MYSQL_RES *result = NULL;
+	MYSQL_ROW row;
+	char *tmp = NULL;
+	char *my_usage_table = NULL;
+	char *query = NULL;
+	List usage_list = NULL;
+	char *id_str = NULL;
+	ListIterator itr = NULL, u_itr = NULL;
+	void *object = NULL;
+	acct_association_rec_t *assoc = NULL;
+	acct_wckey_rec_t *wckey = NULL;
+	acct_accounting_rec_t *accounting_rec = NULL;
+
+	char *usage_req_inx[] = {
+		"t1.id",
+		"t1.period_start",
+		"t1.alloc_cpu_secs"
+	};
+	
+	enum {
+		USAGE_ID,
+		USAGE_START,
+		USAGE_ACPU,
+		USAGE_COUNT
+	};
+
+
+	if(!object_list) {
+		error("We need an object to set data for getting usage");
+		return SLURM_ERROR;
+	}
+
+	if(_check_connection(mysql_conn) != SLURM_SUCCESS)
+		return SLURM_ERROR;
+
+	switch (type) {
+	case DBD_GET_ASSOC_USAGE:
+		itr = list_iterator_create(object_list);
+		while((assoc = list_next(itr))) {
+			if(id_str)
+				xstrfmtcat(id_str, " || t3.id=%d", assoc->id);
+			else
+				xstrfmtcat(id_str, "t3.id=%d", assoc->id);
+		}
+		list_iterator_destroy(itr);
+
+		my_usage_table = assoc_day_table;
+		break;
+	case DBD_GET_WCKEY_USAGE:
+		itr = list_iterator_create(object_list);
+		while((wckey = list_next(itr))) {
+			if(id_str)
+				xstrfmtcat(id_str, " || id=%d", wckey->id);
+			else
+				xstrfmtcat(id_str, "id=%d", wckey->id);
+		}
+		list_iterator_destroy(itr);
+
+		my_usage_table = wckey_day_table;
+		break;
+	default:
+		error("Unknown usage type %d", type);
+		return SLURM_ERROR;
+		break;
+	}
+
+	if(_set_usage_information(&my_usage_table, type, &start, &end)
+	   != SLURM_SUCCESS) {
+		xfree(id_str);
+		return SLURM_ERROR;
+	}
+
+	xfree(tmp);
+	i=0;
+	xstrfmtcat(tmp, "%s", usage_req_inx[i]);
+	for(i=1; i<USAGE_COUNT; i++) {
+		xstrfmtcat(tmp, ", %s", usage_req_inx[i]);
+	}
+	switch (type) {
+	case DBD_GET_ASSOC_USAGE:
+		query = xstrdup_printf(
+			"select %s from %s as t1, %s as t2, %s as t3 "
+			"where (t1.period_start < %d && t1.period_start >= %d) "
+			"&& t1.id=t2.id && (%s) && "
+			"t2.lft between t3.lft and t3.rgt "
+			"order by t1.id, period_start;",
+			tmp, my_usage_table, assoc_table, assoc_table,
+			end, start, id_str);
+		break;
+	case DBD_GET_WCKEY_USAGE:
+		query = xstrdup_printf(
+			"select %s from %s as t1 "
+			"where (period_start < %d && period_start >= %d) "
+			"&& %s order by id, period_start;",
+			tmp, my_usage_table, end, start, id_str);
+		break;
+	default:
+		error("Unknown usage type %d", type);
+		xfree(id_str);
+		xfree(tmp);
+		return SLURM_ERROR;
+		break;
+	}
+	xfree(id_str);
+	xfree(tmp);
+
+	debug4("%d(%d) query\n%s", mysql_conn->conn, __LINE__, query);
+	if(!(result = mysql_db_query_ret(
+		     mysql_conn->db_conn, query, 0))) {
+		xfree(query);
+		return SLURM_ERROR;
+	}
+	xfree(query);
+
+	usage_list = list_create(destroy_acct_accounting_rec);
+
+	while((row = mysql_fetch_row(result))) {
+		acct_accounting_rec_t *accounting_rec =
+			xmalloc(sizeof(acct_accounting_rec_t));
+		accounting_rec->id = atoi(row[USAGE_ID]);
+		accounting_rec->period_start = atoi(row[USAGE_START]);
+		accounting_rec->alloc_secs = atoll(row[USAGE_ACPU]);
+		list_append(usage_list, accounting_rec);
+	}
+	mysql_free_result(result);
+	
+	u_itr = list_iterator_create(usage_list);
+	itr = list_iterator_create(object_list);
+	while((object = list_next(itr))) {
+		int found = 0;
+		int id = 0;
+		List acct_list = NULL;
+
+		switch (type) {
+		case DBD_GET_ASSOC_USAGE:
+			assoc = (acct_association_rec_t *)object;
+			if(!assoc->accounting_list)
+				assoc->accounting_list = list_create(
+					destroy_acct_accounting_rec);
+			acct_list = assoc->accounting_list;
+			id = assoc->id;
+			break;
+		case DBD_GET_WCKEY_USAGE:
+			wckey = (acct_wckey_rec_t *)object;
+			if(!wckey->accounting_list)
+				wckey->accounting_list = list_create(
+					destroy_acct_accounting_rec);
+			acct_list = wckey->accounting_list;
+			id = wckey->id;
+			break;
+		default:
+			continue;
+			break;
+		}
+		
+		while((accounting_rec = list_next(u_itr))) {
+			if(id == accounting_rec->id) {
+				list_append(acct_list, accounting_rec);
+				list_remove(u_itr);
+				found = 1;
+			} else if(found) {
+				/* here we know the
+				   list is in id order so
+				   if the next record
+				   isn't the correct id
+				   just continue since
+				   there is no reason to
+				   go through the rest of
+				   the list when we know
+				   it isn't going to be
+				   the correct id */
+				break;
+			}
+		}
+		list_iterator_reset(u_itr);
+	}
+	list_iterator_destroy(itr);
+	list_iterator_destroy(u_itr);	
+	
+	if(list_count(usage_list))
+		error("we have %d records not added "
+		      "to the association list",
+		      list_count(usage_list));
+	list_destroy(usage_list);
+
+
+	return rc;
+#else
+	return SLURM_ERROR;
+#endif
+}
+
 static mysql_db_info_t *_mysql_acct_create_db_info()
 {
 	mysql_db_info_t *db_info = xmalloc(sizeof(mysql_db_info_t));
@@ -7896,8 +8098,8 @@ empty:
 	list_iterator_destroy(itr);
 	list_iterator_destroy(assoc_itr);
 	if(list_count(assoc_list))
-		info("I have %d left over associations", 
-		     list_count(assoc_list));
+		error("I have %d left over associations", 
+		      list_count(assoc_list));
 	list_destroy(assoc_list);
 
 	return cluster_list;
@@ -8162,13 +8364,6 @@ empty:
 		else
 			assoc->grp_cpu_mins = INFINITE;
 
-		/* get the usage if requested */
-		if(with_usage) {
-			acct_storage_p_get_usage(mysql_conn, uid, assoc,
-						 DBD_GET_ASSOC_USAGE,
-						 assoc_cond->usage_start,
-						 assoc_cond->usage_end);
-		}
 		parent_acct = row[ASSOC_REQ_ACCT];
 		if(!without_parent_info 
 		   && row[ASSOC_REQ_PARENT][0]) {
@@ -8393,6 +8588,12 @@ empty:
 		//info("parent id is %d", assoc->parent_id);
 		//log_assoc_rec(assoc);
 	}
+
+	if(with_usage && assoc_list) 
+		_get_usage_for_list(mysql_conn, DBD_GET_ASSOC_USAGE,
+				    assoc_list, assoc_cond->usage_start,
+				    assoc_cond->usage_end);
+	
 	mysql_free_result(result);
 
 	list_destroy(delta_qos_list);
@@ -8766,17 +8967,15 @@ empty:
 			wckey->name = xstrdup("");
 
 		wckey->cluster = xstrdup(row[WCKEY_REQ_CLUSTER]);
-
-		/* get the usage if requested */
-		if(with_usage) {
-			acct_storage_p_get_usage(mysql_conn, uid, wckey,
-						 DBD_GET_WCKEY_USAGE,
-						 wckey_cond->usage_start,
-						 wckey_cond->usage_end);
-		}		
 	}
 	mysql_free_result(result);
 
+	if(with_usage && wckey_list) 
+		_get_usage_for_list(mysql_conn, DBD_GET_WCKEY_USAGE,
+				    wckey_list, wckey_cond->usage_start,
+				    wckey_cond->usage_end);
+	
+
 	//END_TIMER2("get_wckeys");
 	return wckey_list;
 #else
@@ -9277,7 +9476,7 @@ extern int acct_storage_p_get_usage(mysql_conn_t *mysql_conn, uid_t uid,
 				if(!acct_assoc->acct) {
 					debug("No account name given "
 					      "in association.");
-					goto bad_user;				
+					goto bad_user;			
 				}
 				
 				itr = list_iterator_create(user.coord_accts);
diff --git a/src/sacctmgr/account_functions.c b/src/sacctmgr/account_functions.c
index 65cbeceb46185cea14a38352be49f25c78bb3c9c..e9d5d8a6df07b47ec3e8a4807d6d81fa028c1751 100644
--- a/src/sacctmgr/account_functions.c
+++ b/src/sacctmgr/account_functions.c
@@ -137,6 +137,8 @@ static int _set_cond(int *start, int argc, char *argv[],
 			if(format_list)
 				slurm_addto_char_list(format_list, argv[i]+end);
 		} else if (!strncasecmp (argv[i], "FairShare", 
+					 MAX(command_len, 1))
+			   || !strncasecmp (argv[i], "Shares",
 					 MAX(command_len, 1))) {
 			if(!assoc_cond->fairshare_list)
 				assoc_cond->fairshare_list =
@@ -358,6 +360,8 @@ static int _set_rec(int *start, int argc, char *argv[],
 			acct->description =  strip_quotes(argv[i]+end, NULL, 1);
 			u_set = 1;
 		} else if (!strncasecmp (argv[i], "FairShare", 
+					 MAX(command_len, 1))
+			   || !strncasecmp (argv[i], "Shares",
 					 MAX(command_len, 1))) {
 			if(!assoc)
 				continue;
@@ -1129,6 +1133,12 @@ extern int sacctmgr_list_account(int argc, char *argv[])
 			field->name = xstrdup("Par Name");
 			field->len = 10;
 			field->print_routine = print_fields_str;
+		} else if(!strncasecmp("Shares", object,
+				       MAX(command_len, 1))) {
+			field->type = PRINT_FAIRSHARE;
+			field->name = xstrdup("Shares");
+			field->len = 9;
+			field->print_routine = print_fields_uint;
 		} else if(!strncasecmp("User", object, MAX(command_len, 1))) {
 			field->type = PRINT_USER;
 			field->name = xstrdup("User");
diff --git a/src/sacctmgr/association_functions.c b/src/sacctmgr/association_functions.c
index 788554cd62ef392904f84924507e443b9f5d7527..80203e679ff7277b5b768fae14c555f67961a039 100644
--- a/src/sacctmgr/association_functions.c
+++ b/src/sacctmgr/association_functions.c
@@ -132,6 +132,8 @@ static int _set_cond(int *start, int argc, char *argv[],
 				slurm_addto_char_list(format_list,
 						      argv[i]+end);
 		} else if (!strncasecmp (argv[i], "FairShare",
+					 MAX(command_len, 1))
+			   || !strncasecmp (argv[i], "Shares",
 					 MAX(command_len, 1))) {
 			if(!assoc_cond->fairshare_list)
 				assoc_cond->fairshare_list =
@@ -377,7 +379,7 @@ extern int sacctmgr_list_association(int argc, char *argv[])
 		field = xmalloc(sizeof(print_field_t));
 
 		if(!strncasecmp("Account", object, MAX(command_len, 1))
-		   || !strncasecmp ("Acct", object, MAX(command_len, 4))) {
+		   || !strncasecmp("Acct", object, MAX(command_len, 4))) {
 			field->type = PRINT_ACCOUNT;
 			field->name = xstrdup("Account");
 			if(tree_display)
@@ -526,6 +528,12 @@ extern int sacctmgr_list_association(int argc, char *argv[])
 			field->name = xstrdup("RGT");
 			field->len = 6;
 			field->print_routine = print_fields_uint;
+		} else if(!strncasecmp("Shares", object,
+				       MAX(command_len, 1))) {
+			field->type = PRINT_FAIRSHARE;
+			field->name = xstrdup("Shares");
+			field->len = 9;
+			field->print_routine = print_fields_uint;
 		} else if(!strncasecmp("User", object, MAX(command_len, 1))) {
 			field->type = PRINT_USER;
 			field->name = xstrdup("User");
diff --git a/src/sacctmgr/cluster_functions.c b/src/sacctmgr/cluster_functions.c
index a5613b3eac2f16cbe2535ae61300b018bee3a6fd..d1b4bd6b36a7d699a134823049c32709ad117b4f 100644
--- a/src/sacctmgr/cluster_functions.c
+++ b/src/sacctmgr/cluster_functions.c
@@ -131,6 +131,8 @@ static int _set_rec(int *start, int argc, char *argv[],
 			if(name_list)
 				slurm_addto_char_list(name_list, argv[i]+end);
 		} else if (!strncasecmp (argv[i], "FairShare", 
+					 MAX(command_len, 1))
+			   || !strncasecmp (argv[i], "Shares",
 					 MAX(command_len, 1))) {
 			if (get_uint(argv[i]+end, &assoc->shares_raw, 
 			    "FairShare") == SLURM_SUCCESS)
@@ -568,6 +570,12 @@ extern int sacctmgr_list_cluster(int argc, char *argv[])
 			field->name = xstrdup("RPC");
 			field->len = 3;
 			field->print_routine = print_fields_uint;
+		} else if(!strncasecmp("Shares", object, 
+				       MAX(command_len, 1))) {
+			field->type = PRINT_FAIRSHARE;
+			field->name = xstrdup("Shares");
+			field->len = 9;
+			field->print_routine = print_fields_uint;
 		} else {
 			exit_code=1;
 			fprintf(stderr, "Unknown field '%s'\n", object);
diff --git a/src/sacctmgr/file_functions.c b/src/sacctmgr/file_functions.c
index 3b841b049ba0929e4567351902f33bef7323ec39..ef8c8a8183bc028bf4ea8620176ee636abafa89f 100644
--- a/src/sacctmgr/file_functions.c
+++ b/src/sacctmgr/file_functions.c
@@ -337,6 +337,8 @@ static sacctmgr_file_opts_t *_parse_options(char *options)
 					 MAX(command_len, 3))) {
 			file_opts->desc = xstrdup(option);
 		} else if (!strncasecmp (sub, "FairShare", 
+					 MAX(command_len, 1))
+			   || !strncasecmp (sub, "Shares",
 					 MAX(command_len, 1))) {
 			if (get_uint(option, &file_opts->fairshare, 
 			    "FairShare") != SLURM_SUCCESS) {
@@ -585,7 +587,9 @@ static List _set_up_print_fields(List format_list)
 			field->len = 20;
 			field->print_routine = print_fields_str;
 		} else if(!strncasecmp("FairShare", object, 
-				       MAX(command_len, 1))) {
+				       MAX(command_len, 1))
+			  || !strncasecmp("Shares", object, 
+					  MAX(command_len, 1))) {
 			field->type = PRINT_FAIRSHARE;
 			field->name = xstrdup("FairShare");
 			field->len = 9;
diff --git a/src/sacctmgr/user_functions.c b/src/sacctmgr/user_functions.c
index 261548ffb0204696d6a44596fc069c8e40fd8760..7d50ca8a7b7907fcd03eb7a676a439d8a6f9695a 100644
--- a/src/sacctmgr/user_functions.c
+++ b/src/sacctmgr/user_functions.c
@@ -160,6 +160,8 @@ static int _set_cond(int *start, int argc, char *argv[],
 			if(format_list)
 				slurm_addto_char_list(format_list, argv[i]+end);
 		} else if (!strncasecmp (argv[i], "FairShare", 
+					 MAX(command_len, 1))
+			   || !strncasecmp (argv[i], "Shares",
 					 MAX(command_len, 1))) {
 			if(!assoc_cond->fairshare_list)
 				assoc_cond->fairshare_list =
@@ -373,6 +375,8 @@ static int _set_rec(int *start, int argc, char *argv[],
 				strip_quotes(argv[i]+end, NULL, 1);
 			u_set = 1;
 		} else if (!strncasecmp (argv[i], "FairShare",
+					 MAX(command_len, 1))
+			   || !strncasecmp (argv[i], "Shares",
 					 MAX(command_len, 1))) {
 			if(!assoc)
 				continue;
@@ -744,6 +748,8 @@ extern int sacctmgr_add_user(int argc, char *argv[])
 			slurm_addto_char_list(wckey_cond->name_list,
 					      default_wckey);
 		} else if (!strncasecmp (argv[i], "FairShare",
+					 MAX(command_len, 1))
+			   || !strncasecmp (argv[i], "Shares",
 					 MAX(command_len, 1))) {
 			if (get_uint(argv[i]+end, &start_assoc.shares_raw, 
 			    "FairShare") == SLURM_SUCCESS)
@@ -1686,6 +1692,12 @@ extern int sacctmgr_list_user(int argc, char *argv[])
 			field->name = xstrdup("Partition");
 			field->len = 10;
 			field->print_routine = print_fields_str;
+		} else if(!strncasecmp("Shares", object,
+				       MAX(command_len, 1))) {
+			field->type = PRINT_FAIRSHARE;
+			field->name = xstrdup("Shares");
+			field->len = 9;
+			field->print_routine = print_fields_uint;
 		} else if(!strncasecmp("User", object, MAX(command_len, 1))
 			  || !strncasecmp("Name", object, 
 					  MAX(command_len, 2))) {
diff --git a/src/sreport/user_reports.c b/src/sreport/user_reports.c
index 5a1a545dd3c9d5686a54439483d5d356d88c53e0..bf751f180f71724dcedf7bf5737904e3be516df5 100644
--- a/src/sreport/user_reports.c
+++ b/src/sreport/user_reports.c
@@ -76,7 +76,7 @@ static int _set_cond(int *start, int argc, char *argv[],
 		user_cond->assoc_cond->with_usage = 1;
 	}
 	assoc_cond = user_cond->assoc_cond;
-
+	
 	if(!assoc_cond->cluster_list)
 		assoc_cond->cluster_list = list_create(slurm_destroy_char);
 	for (i=(*start); i<argc; i++) {
@@ -265,6 +265,8 @@ extern int user_top(int argc, char *argv[])
 
 	_set_cond(&i, argc, argv, user_cond, format_list);
 
+	user_cond->assoc_cond->without_parent_info = 1;
+
 	if(!list_count(format_list)) 
 		slurm_addto_char_list(format_list, "Cl,L,P,A,U");